define(['exports'], (function(exports) {
	'use strict';

	//按钮功能触发方式
	var FuncButtonTrigger;
	(function(FuncButtonTrigger) {
		//拖拽
		FuncButtonTrigger[FuncButtonTrigger["drag"] = 0] = "drag";
		//点击
		FuncButtonTrigger[FuncButtonTrigger["click"] = 1] = "click";
		//长按
		FuncButtonTrigger[FuncButtonTrigger["longpress"] = 2] = "longpress";
		//双击
		FuncButtonTrigger[FuncButtonTrigger["dbclick"] = 3] = "dbclick";
	})(FuncButtonTrigger || (FuncButtonTrigger = {}));
	//撤销重做种类枚举
	var OperationTypeEmum;
	(function(OperationTypeEmum) {
		//大小
		OperationTypeEmum[OperationTypeEmum["size"] = 0] = "size";
		//位置
		OperationTypeEmum[OperationTypeEmum["position"] = 1] = "position";
		//角度
		OperationTypeEmum[OperationTypeEmum["angle"] = 2] = "angle";
		//镜像
		OperationTypeEmum[OperationTypeEmum["mirror"] = 3] = "mirror";
		//
	})(OperationTypeEmum || (OperationTypeEmum = {}));
	exports.ViewObjectFamily = void 0;
	(function(ViewObjectFamily) {
		ViewObjectFamily[ViewObjectFamily["image"] = 0] = "image";
		ViewObjectFamily[ViewObjectFamily["write"] = 1] = "write";
		ViewObjectFamily[ViewObjectFamily["line"] = 2] = "line";
		ViewObjectFamily[ViewObjectFamily["circle"] = 3] = "circle";
		ViewObjectFamily[ViewObjectFamily["rect"] = 4] = "rect";
		ViewObjectFamily[ViewObjectFamily["text"] = 5] = "text";
	})(exports.ViewObjectFamily || (exports.ViewObjectFamily = {}));

	class Vector {
		constructor(x, y) {
			this.x = 0;
			this.y = 0;
			this.x = x;
			this.y = y;
		}
		add(v) {
			this.x += v.x;
			this.y += v.y;
		}
		sub(v) {
			this.x -= v.x;
			this.y -= v.y;
			return this;
		}
		mult(v) {
			this.x *= v.x;
			this.y *= v.y;
			return this;
		}
		div(v) {
			this.x /= v.x;
			this.y /= v.y;
			return this;
		}
		mag() {
			return Math.sqrt(this.x * this.x + this.y * this.y);
		}
		dist(v) {
			let dx = this.x - v.x;
			let dy = this.y - v.y;
			return Math.sqrt(dx * dx + dy * dy);
		}
		normalize() {
			let len = this.mag();
			this.x /= len;
			this.y /= len;
			return this;
		}
		clamp(c) {
			let [max, min] = c;
			this.x = Math.min(Math.max(this.x, min), max);
			this.y = Math.min(Math.max(this.y, min), max);
		}
		copy() {
			return new Vector(this.x, this.y);
		}
		set(v) {
			this.x = v.x;
			this.y = v.y;
		}
		setXY(x, y) {
			this.x = x;
			this.y = y;
		}
		toJson() {
			return {
				x: this.x,
				y: this.y,
			};
		}
		troweling() {
			this.x = this.x >> 0;
			this.y = this.y >> 0;
			return this;
		}
		equals(v) {
			return v.x == this.x && v.y == this.y;
		}
		toArray() {
			return [this.x, this.y];
		}
		static dist(v1, v2) {
			let sub = Vector.sub(v1, v2);
			return Vector.mag(sub);
		}
		static mag(v) {
			return Math.sqrt(v.x * v.x + v.y * v.y);
		}
		static sub(v1, v2) {
			return new Vector(v1.x - v2.x, v1.y - v2.y);
		}
		static add(v1, v2) {
			return new Vector(v1.x + v2.x, v1.y + v2.y);
		}
		static troweling(v) {
			v.x = v.x >> 0;
			v.y = v.y >> 0;
			return v;
		}
	}

	class Point extends Vector {
		constructor(x, y) {
			super(x, y);
		}
		toArray() {
			return [this.x, this.y];
		}
	}
	/**
	 * 包裹图片Rect的矩阵点，通常为4个点
	 */
	class Vertex {
		constructor(points) {
			this.points = new Array();
			this.points = points.map((item) => {
				const [x, y] = item;
				return new Point(x, y);
			});
		}
		setPoints(points) {
			this.points = points;
		}
		getPoints() {
			return this.points;
		}
		/**
		 * @description 根据传入角度，旋转该类的顶点
		 * @param angle
		 * @param rect
		 */
		rotate(angle, rect) {
			const cos_ = Math.cos(angle),
				sin_ = Math.sin(angle);
			const rotateAngle = (point) => {
				const x = point.x * cos_ - point.y * sin_;
				const y = point.x * sin_ + point.y * cos_;
				return [x, y];
				// const mf = [
				// 	[cos_, (sin_*-1) , 0],
				// 	[sin_, cos_, 0],
				// 	[0, 0, 1]
				// ];
			};
			const len = this.points.length;
			for (let i = 0; i < len; i++) {
				const point = this.points[i];
				const [x, y] = rotateAngle(point);
				point.x = x + rect.position.x;
				point.y = y + rect.position.y;
			}
		}
		/**
		 * @description 矫正位置
		 * @param rect
		 */
		correctPosition(rect) {
			const len = this.points.length;
			for (let i = 0; i < len; i++) {
				const point = this.points[i];
				point.x += rect.position.x;
				point.y += rect.position.y;
			}
		}
		drawPoints(paint) {
			this.points.forEach((point) => {
				paint.fillRect(point.x, point.y, 3, 3);
			});
		}
	}

	class Line {
		constructor(p1, p2) {
			this.p1 = p1;
			this.p2 = p2;
		}
	}
	class CheckInside {
		onLine(l1, p) {
			// Check whether p is on the line or not
			if (p.x <= Math.max(l1.p1.x, l1.p2.x) &&
				p.x <= Math.min(l1.p1.x, l1.p2.x) &&
				(p.y <= Math.max(l1.p1.y, l1.p2.y) &&
					p.y <= Math.min(l1.p1.y, l1.p2.y)))
				return true;
			return false;
		}
		/**
		 * @param {Vector} p1
		 * @param {Vector} p2
		 * @param {Object} radius
		 */
		checkInsideArc(p1, p2, radius) {
			return Vector.dist(p1, p2) < radius;
		}
		direction(a, b, c) {
			let val = (b.y - a.y) * (c.x - b.x) -
				(b.x - a.x) * (c.y - b.y);
			if (val == 0)
				// Colinear
				return 0;
			else if (val < 0)
				// Anti-clockwise direction
				return 2;
			// Clockwise direction
			return 1;
		}
		isIntersect(l1, l2) {
			// Four direction for two lines and points of other line
			let dir1 = this.direction(l1.p1, l1.p2, l2.p1);
			let dir2 = this.direction(l1.p1, l1.p2, l2.p2);
			let dir3 = this.direction(l2.p1, l2.p2, l1.p1);
			let dir4 = this.direction(l2.p1, l2.p2, l1.p2);
			// When intersecting
			if (dir1 != dir2 && dir3 != dir4)
				return true;
			// When p2 of line2 are on the line1
			if (dir1 == 0 && this.onLine(l1, l2.p1))
				return true;
			// When p1 of line2 are on the line1
			if (dir2 == 0 && this.onLine(l1, l2.p2))
				return true;
			// When p2 of line1 are on the line2
			if (dir3 == 0 && this.onLine(l2, l1.p1))
				return true;
			// When p1 of line1 are on the line2
			if (dir4 == 0 && this.onLine(l2, l1.p2))
				return true;
			return false;
		}
		checkInside(poly, n, p) {
			// When polygon has less than 3 edge, it is not polygon
			if (n < 3)
				return false;
			// Create a point at infinity, y is same as point p
			let tmp = new Point(9999, p.y);
			let exline = new Line(p, tmp);
			let count = 0;
			let i = 0;
			do {
				// Forming a line from two consecutive points of
				// poly
				let side = new Line(poly[i], poly[(i + 1) % n]);
				if (this.isIntersect(side, exline)) {
					// If side is intersects exline
					if (this.direction(side.p1, p, side.p2) == 0)
						return this.onLine(side, p);
					count++;
				}
				i = (i + 1) % n;
			} while (i != 0);
			// When count is odd
			return count & 1;
		}
	}
	// Driver code
	// let polygon = [new Point(0, 0), new Point(10, 0), new Point(10, 10), new Point(0, 10)];
	// let p = new Point(5, 3);
	// let n = 4;
	// //  call
	// if (checkInside(polygon, n, p))
	// 	console.log("Point is inside.");
	// else
	// 	console.log("Point is outside.");
	// This code is contributed by poojaagarwal2.

	class CatchPointUtil {
		/**
		 *
		 * @param ViewObject
		 * @param event
		 * @returns
		 */
		static catchViewObject(ViewObjectList, position) {
			const len = ViewObjectList.length - 1;
			for (let i = len; i >= 0; i--) {
				const item = ViewObjectList[i];
				//隐藏过后不需要检测位置
				if (item.disabled)
					continue;
				if (CatchPointUtil.inArea(item.rect, position)) {
					return item;
				}
			}
			return null;
		}
		static inArea(rect, position) {
			var _a;
			if (!rect.vertex)
				return false;
			const points = (_a = rect.vertex) === null || _a === void 0 ? void 0 : _a.getPoints();
			const point = new Point(position.x, position.y);
			return !!CatchPointUtil._checkInside.checkInside(points, 4, point);
		}
		/**
		 * @param {Vector} p1
		 * @param {Vector} p2
		 * @param {Object} radius
		 */
		static checkInsideArc(p1, p2, radius) {
			return Vector.dist(p1, p2) < radius;
		}
	}
	CatchPointUtil._checkInside = new CheckInside;

	//操作记录
	class Recorder {
		constructor() {
			//上一步状态
			this.cache = null;
			//现在的状态
			this.now = null;
			//左栈
			this.stack = [];
			//右栈
			this.undoStack = [];
			//最大历史记录栈长度
			this.maxLength = 30;
			//目前状态
			this.currentValue = null;
		}
		static getInstance() {
			return Recorder._recorder;
		}
		get len() {
			return this.stack.length;
		}
		get undoLen() {
			return this.undoStack.length;
		}
		last() {
			return this.stack[this.len - 1];
		}
		undoLast() {
			return this.undoLast[this.undoLen - 1];
		}
		get isFull() {
			return this.len > this.maxLength;
		}
		setCache(node) {
			//不为空时赋值，或者不是同一个时
			if (this.cache != null) {
				return;
			}
			this.cache = node;
		}
		setNow(node) {
			this.now = node;
		}
		push(node) {
			if (node == null)
				return;
			this.stack.push(node);
			this.undoStack = [];
			this.currentValue = node;
			if (this.isFull)
				this.stack.shift();
		}
		fallback() {
			if (this.len <= 1)
				return Promise.resolve(null);
			const rect = this.stack.pop();
			this.undoStack.push(rect);
			this.currentValue = this.last();
			//以key为判断，如果相邻的Node不同master key，说明换了master,需要掐头
			if (rect.key != this.currentValue.key) {
				const rect = this.stack.pop();
				this.undoStack.push(rect);
				this.currentValue = this.last();
			}
			return Promise.resolve(this.currentValue);
		}
		cancelFallback() {
			if (this.undoLen == 0)
				return Promise.resolve(null);
			if (this.undoLen > 0) {
				//以key为判断，如果相邻的Node不同master key，说明换了master,需要掐头
				if (this.undoStack[this.undoLen - 1].key != this.currentValue.key) {
					const rect = this.undoStack.pop();
					this.stack.push(rect);
					this.currentValue = this.last();
				}
			}
			const rect = this.undoStack.pop();
			this.stack.push(rect);
			this.currentValue = this.last();
			return Promise.resolve(this.currentValue);
		}
		commit() {
			if (this.cache == null)
				return;
			//当栈为0,需要存左端的，或者前与后key不一致,或者前后操作不一致
			const notOne = this.stack.length != 0 ? (this.cache.key != this.last().key) || (this.cache
				.type != this.last().type) : false;
			if (this.stack.length == 0 || notOne)
				this.push(this.cache);
			this.push(this.now);
			this.cache = null;
			//  console.log(this.stack);
		}
	}
	//单例模式
	Recorder._recorder = new Recorder();

	//防抖
	const Debounce = (fun, delay) => {
		let timer = null;
		return (args) => {
			if (timer != null)
				clearTimeout(timer);
			timer = setTimeout(() => {
				fun(args);
			}, delay);
		};
	};
	//节流
	const Throttle = (fun, delay) => {
		let lastTime = 0;
		return (args) => {
			let nowTime = new Date().getTime();
			if (nowTime - lastTime < delay)
				return;
			fun(args);
			lastTime = nowTime;
		};
	};
	/**
	 * 返回某个实例化对象是否等于某个类
	 * @param obj 实例化对象
	 * @param obj2 类名
	 * @returns
	 */
	const classTypeIs = (obj, obj2) => {
		const clazzName1 = obj === null || obj === void 0 ? void 0 : obj.constructor.name;
		return clazzName1 == (obj2 === null || obj2 === void 0 ? void 0 : obj2.name);
	};
	/**
	 * @description 1inch=72pt
	 * @param inch
	 */
	const inToPx = (inch) => {
		return ptToPx(inch * 72);
	};
	/**
	 * @description 1inch=25.5 mm
	 * @param mm
	 * @returns
	 */
	const mmToIn = (mm) => {
		return (mm / 25.4);
	};
	/**
	 * @description 1pt是一英镑=1/72(inch)英寸   取dpi=96
	 * 得到    px=(pt/72)*96
	 * @param pt
	 */
	const ptToPx = (pt) => {
		return Math.round((pt / 72) * 96);
	};

	/**
	 * 被观察者应该实现的抽象类
	 */
	class ObserverObj {
		constructor() {
			this.observer = null;
		}
		addObserver(observer) {
			this.observer = observer;
		}
		removeObserver() {
			this.observer = null;
		}
	}
	class Observer {
		constructor(master) {
			this.master = master;
		}
		report(value, type) {
			this.master.report(value, type);
		}
		beforeReport(value, type) {
			this.master.beforeReport(value, type);
		}
	}
	/**
	 * 操作监听节点
	 * 监听栈节点
	 * 每个节点都分为不同总类
	 * 枚举
	 * 根据枚举节点存储不同的数据
	 */
	class RecordNode {
		constructor(type) {
			//节点的key
			this._key = Math.random().toString(12).substring(2);
			this._type = type;
		}
		setData(data) {
			this._data = data;
		}
		get data() {
			return this._data;
		}
		get type() {
			return this._type;
		}
	}
	/**
	 * 存历史记录节点
	 */
	class Record {
		constructor() {
			this.recorder = Recorder.getInstance();
			this.debounceNow = Debounce((args) => {
				const {
					value,
					type,
					master
				} = args;
				const now = this.getNode(value, type, master);
				this.recorder.setNow(now);
			}, 0);
			this.debounceBefore = Throttle((args) => {
				const {
					value,
					type,
					master
				} = args;
				const before = this.getNode(value, type, master);
				this.recorder.setCache(before);
			}, 100);
		}
		//记录现在的窗台
		recordNow(value, type, master) {
			this.debounceNow({
				value,
				type,
				master
			});
		}
		//记录现在的窗台
		recordBefore(value, type, master) {
			this.debounceBefore({
				value,
				type,
				master
			});
		}
		/**
		 * 处理数据并得到一个记录节点，记录节点不处理什么深拷贝浅拷贝的，只负责存储
		 * 在传过来调用这个函数之前务必处理好深浅拷贝，谁知道你传过来的是什么类型
		 * @param value
		 * @param type
		 */
		getNode(value, type, master) {
			const node = new RecordNode(type);
			node.setData(value);
			node.key = master.key;
			return node;
		}
	}
	/**
	 * 如果需要撤销操作，组件必须继承该抽象类实现
	 */
	class OperationObserver {
		constructor() {
			this.recordClazz = new Record();
		}
		onHide() {}
		/**
		 * 添加被观察者
		 * @param obj
		 */
		addObserver(obj) {
			this.obj = obj;
			this.obj.rect.addObserver(new Observer(this));
		}
		/**
		 * 改变后
		 * 记录,先粗略copy对象存储，后如需优化可以转json存储
		 */
		record(value, type) {
			//设置现在的状态
			this.recordClazz.recordNow(value, type, this.obj);
		}
		/**
		 * @description 改变前
		 * @param value
		 * @param type
		 */
		beforeReport(value, type) {
			//设置旧的状态
			this.recordClazz.recordBefore(value, type, this.obj);
		}
		/**
		 * 汇报观察情况，调用对应函数
		 * @param value
		 * @param type
		 */
		report(value, type) {
			this.record(value, type);
			switch (type) {
				case "size":
					this.didChangeSize(value);
					break;
				case "angle":
					this.didChangeAngle(value);
					break;
				case "scale":
					this.didChangeScale(value);
					break;
				case "position":
					this.didChangePosition(value);
					break;
				case "drag":
					this.didDrag(value);
					break;
			}
		}
		//移除观察者
		removeObserver() {
			this.obj.rect.removeObserver();
		}
		//改变角度
		didChangeAngle(angle) {}
		didChangeSize(size) {}
		didChangePosition(position) {}
		didChangeScale(scale) {}
		didDrag(value) {}
	}

	class Size {
		constructor(width, height) {
			this.width = width;
			this.height = height;
		}
		toVector() {
			return new Vector(this.width, this.height);
		}
		copy() {
			return new Size(this.width, this.height);
		}
	}
	class Rect extends ObserverObj {
		constructor(params, key, options) {
			super();
			this._angle = 0;
			this.key = Math.random().toString(16).substring(2);
			const {
				width,
				height,
				x,
				y
			} = params || {
				x: 0,
				y: 0,
				width: 0,
				height: 0,
			};
			this._size = new Size(width, height);
			this._position = new Vector(x || 0, y || 0);
			if (key) {
				this.key = key;
			}
			if (options) {
				const {
					angle
				} = options;
				this.setAngle(angle);
			}
		}
		updateVertex() {
			const half_w = this._size.width * .5,
				half_h = this._size.height * .5;
			this._vertex = new Vertex([
				[-half_w, -half_h],
				[+half_w, -half_h],
				[+half_w, +half_h],
				[-half_w, +half_h],
			]);
			this._vertex.rotate(this.getAngle, this);
		}
		get position() {
			return this._position;
		}
		get size() {
			return this._size;
		}
		get scale() {
			return this._scale;
		}
		get vertex() {
			return this._vertex;
		}
		get getAngle() {
			return this._angle;
		}
		set position(position) {
			this.beforeReport(position, "position");
			this._position = position;
			this._position.x = ~~this._position.x;
			this._position.y = ~~this._position.y;
			this.report(position, "position");
		}
		setPosition(position) {
			this.beforeReport(position, "position");
			this._position = position;
			this._position.x = ~~this._position.x;
			this._position.y = ~~this._position.y;
			this.report(position, "position");
		}
		setScale(scale, change) {
			this.beforeReport(scale, "scale");
			//是否真正改变大小，还是之通知倍数改变了，后续可以考虑移除监听scale
			if (change !== null && change !== void 0 ? change : true) {
				this._size.width *= scale;
				this._size.height *= scale;
			}
			this.report(scale, "scale");
		}
		/**
		 * @description 拖拽处需要表明拖拽
		 * @param width
		 * @param height
		 */
		setSize(width, height, isDrag) {
			//之前
			if (isDrag)
				this.beforeReport({
					size: new Size(width, height),
					angle: this._angle
				}, "drag");
			else
				this.beforeReport(new Size(width, height), "size");
			this._size.width = ~~width;
			this._size.height = ~~height;
			//之后
			if (isDrag)
				this.report({
					size: new Size(width, height),
					angle: this._angle
				}, "drag");
			else
				this.report(new Size(width, height), "size");
		}
		setAngle(angle, isDrag) {
			//之前
			if (isDrag)
				this.beforeReport({
					size: this._size.copy(),
					angle: this._angle
				}, "drag");
			else
				this.beforeReport(angle, "angle");
			this._angle = angle;
			if (isDrag)
				this.report({
					size: this._size.copy(),
					angle: this._angle
				}, "drag");
			else
				this.report(angle, "angle");
		}
		/**
		 * @description 向观察者汇报自己的变化情况
		 * @param value
		 * @param type
		 * @returns
		 */
		report(value, type) {
			if (this.observer == null)
				return;
			this.observer.report(value, type);
		}
		/**
		 * @description 向观察者汇报自己的变化情况之前
		 * @param value
		 * @param type
		 * @returns
		 */
		beforeReport(value, type) {
			if (this.observer == null)
				return;
			this.observer.beforeReport(value, type);
		}
		copy(key) {
			return new Rect({
				width: this._size.width,
				height: this._size.height,
				x: this._position.x,
				y: this._position.y,
			}, key, {
				angle: this.getAngle
			});
		}
		set(newRect) {
			this.position.set(newRect.position);
			this.setAngle(newRect.getAngle);
			this.setScale(newRect.scale);
			this.setSize(newRect.size.width, newRect.size.height);
		}
	}

	//按钮抽象类
	class Button {
		constructor(master) {
			this.name = "";
			//隐藏
			this.disabled = false;
			this.rect = new Rect();
			this.relativeRect = new Rect();
			//渲染UI按钮半径
			this.radius = 20;
			//点击感应范围
			this.senseRadius = 20;
			//是否能被锁住
			this.canBeeLocking = true;
			this.master = master;
		}
		//能被锁住就不是自由的
		get isFree() {
			return !this.canBeeLocking;
		}
		set free(canBeeLocking) {
			this.canBeeLocking = !canBeeLocking;
		}
		/**
		 * 充值按钮坐标
		 */
		reset() {
			this.init(this.options);
		}
		/**
		 * @description 设置相对定位
		 * @param options
		 */
		init(options) {
			if (this.disabled)
				return;
			this.options = options;
			const {
				percentage,
				position
			} = options;
			if (percentage)
				this.setRelativePositionRect(percentage);
			else if (position)
				this.setRelativePosition(position);
			if (!this.originPositionWithSize)
				this.originPositionWithSize = {
					offsetx: ~~(this.relativeRect.position.x),
					offsety: ~~(this.relativeRect.position.y),
				};
			this.setAbsolutePosition();
			this.oldAngle = Math.atan2(~~this.relativeRect.position.y, ~~this.relativeRect.position.x);
			//相对定位到中心的距离
			this.originDistance = Vector.mag(this.relativeRect.position);
			let scaleWidth = 0,
				scaleHeight = 0;
			if (this.relativeRect.position.x != 0) {
				scaleWidth = this.master.rect.size.width / this.relativeRect.position.x;
			}
			if (this.relativeRect.position.y != 0) {
				scaleHeight = this.master.rect.size.height / this.relativeRect.position.y;
			}
			/**
			 * 获取比例关系，后续依赖这个关系改变
			 * 关于 scale=1时，由于是相对定位，且 1/n=n,所以在等于1时需要做特殊处理
			 */
			// this.scaleWithMaster = new Vector(scaleWidth == 1 ? 0 : scaleWidth, scaleHeight == 1 ? 0 : scaleHeight);
			this.scaleWithMaster = new Vector(scaleWidth, scaleHeight);
		}
		get getAbsolutePosition() {
			return Vector.add(this.relativeRect.position, this.master.rect.position);
		}
		get getRelativePosition() {
			return this.relativeRect.position;
		}
		setAbsolutePosition(vector) {
			this.rect.position = vector || this.getAbsolutePosition;
		}
		isInArea(event, target) {
			if (this.master.isLock && this.canBeeLocking)
				return false;
			return CatchPointUtil.checkInsideArc(target, event, this.senseRadius);
		}
		/**
		 * @description 根据父Box的大小宽度比作为基础定位
		 * @param percentage ,占比值，四个点坐标
		 */
		setRelativePositionRect(percentage) {
			const {
				width,
				height
			} = this.master.rect.size;
			const [percent_x, percent_y] = percentage;
			//更改相对定位，看好了，这可是按钮类里面的
			this.relativeRect.position = new Vector(width * percent_x, height * percent_y);
		}
		updateRelativePosition() {
			const master = this.master.rect.size;
			const {
				width,
				height
			} = master;
			let newWidth = width / this.scaleWithMaster.x,
				newHeight = height / this.scaleWithMaster.y;
			if (this.scaleWithMaster.x == 0)
				newWidth = 0;
			if (this.scaleWithMaster.y == 0)
				newHeight = 0;
			this.relativeRect.position.setXY(newWidth, newHeight);
			this.originDistance = Vector.mag(this.relativeRect.position);
		}
		setRelativePosition(position) {
			this.relativeRect.position = position;
		}
		hide() {
			this.disabled = true;
		}
	}

	class GestiConfig {
		constructor(config) {
			var _a, _b;
			if (!config)
				return;
			//默认开启辅助参考线
			GestiConfig.auxiliary = (_a = config === null || config === void 0 ? void 0 : config
				.auxiliary) !== null && _a !== void 0 ? _a : true;
			GestiConfig.dashedLine = (_b = config === null || config === void 0 ? void 0 : config
				.dashedLine) !== null && _b !== void 0 ? _b : true;
		}
		setParams(config) {
			var _a, _b;
			if (!config)
				return;
			//默认开启辅助参考线
			GestiConfig.auxiliary = (_a = config === null || config === void 0 ? void 0 : config
				.auxiliary) !== null && _a !== void 0 ? _a : true;
			GestiConfig.dashedLine = (_b = config === null || config === void 0 ? void 0 : config
				.dashedLine) !== null && _b !== void 0 ? _b : true;
		}
	}
	//开启辅助参考线
	GestiConfig.auxiliary = true;
	GestiConfig.dashedLine = true;
	//Gesti 颜色配置
	GestiConfig.theme = {
		//被选中后边框的颜色
		selectedBorderColor: "#ffffff",
		//按钮背景颜色
		buttonsBgColor: "#ffffff",
		//按钮图标颜色
		buttonIconColor: "#c1c1c1",
		//文字被选中后蒙版颜色
		textSelectedMaskBgColor: "rgba(0,0,0,.1)",
		//辅助线颜色
		auxiliaryDashedLineColor: "#999",
		//包裹对象虚线颜色
		dashedLineColor: "#999",
	};

	/*使用Canvas渲染一些小部件*/
	class Widgets {
		/**
		 * @description 拖拽按钮
		 * @param {Object} paint
		 * @param {Vector} offset
		 */
		static drawGrag(paint, offset) {
			const scale = .08;
			const {
				offsetx,
				offsety
			} = offset;
			// 填充三角形
			paint.beginPath();
			paint.strokeStyle = GestiConfig.theme.buttonIconColor;
			paint.fillStyle = GestiConfig.theme.buttonIconColor;
			paint.moveTo(25 * scale + offsetx, 25 * scale + offsety);
			paint.lineTo(105 * scale + offsetx, 25 * scale + offsety);
			paint.lineTo(25 * scale + offsetx, 105 * scale + offsety);
			paint.fill();
			paint.moveTo(125 * scale + offsetx, 125 * scale + offsety);
			paint.lineTo(125 * scale + offsetx, 45 * scale + offsety);
			paint.lineTo(45 * scale + offsetx, 125 * scale + offsety);
			paint.closePath();
			paint.fill();
		}
		/**
		 * @description 拖拽按钮
		 * @param {Object} paint
		 * @param {Vector} offset
		 */
		static drawRotate(paint, offset) {
			paint.lineWidth = 1;
			const {
				offsetx,
				offsety
			} = offset;
			// 填充三角形
			paint.beginPath();
			paint.fillStyle = GestiConfig.theme.buttonIconColor;
			paint.strokeStyle = GestiConfig.theme.buttonIconColor;
			paint.arc(offsetx, offsety, 4, 0, Math.PI * .6);
			paint.stroke();
			paint.closePath();
			paint.beginPath();
			paint.fillStyle = GestiConfig.theme.buttonIconColor;
			paint.strokeStyle = GestiConfig.theme.buttonIconColor;
			paint.arc(offsetx, offsety, 4, Math.PI, Math.PI * 1.6);
			paint.stroke();
			paint.closePath();
		}
		/**
		 * @description 镜像翻转
		 * @param paint
		 * @param offset
		 */
		static drawMirror(paint, offset) {
			const scale = .3;
			const {
				offsetx,
				offsety
			} = offset;
			paint.beginPath();
			paint.fillStyle = GestiConfig.theme.buttonIconColor;
			paint.strokeStyle = GestiConfig.theme.buttonIconColor;
			paint.moveTo(10 * scale + offsetx, 5 * scale + offsety);
			paint.lineTo(0 * scale + offsetx, 15 * scale + offsety);
			paint.lineTo(10 * scale + offsetx, 25 * scale + offsety);
			paint.moveTo(30 * scale + offsetx, 5 * scale + offsety);
			paint.lineTo(40 * scale + offsetx, 15 * scale + offsety);
			paint.lineTo(30 * scale + offsetx, 25 * scale + offsety);
			paint.moveTo(17 * scale + offsetx, 0 * scale + offsety);
			paint.lineTo(23 * scale + offsetx, 0 * scale + offsety);
			paint.lineTo(23 * scale + offsetx, 30 * scale + offsety);
			paint.lineTo(17 * scale + offsetx, 30 * scale + offsety);
			paint.closePath();
			paint.fill();
		}
		/**
		 * @description 删除
		 * @param paint
		 * @param offset
		 */
		static drawClose(paint, offset) {
			const scale = .7;
			const {
				offsetx,
				offsety
			} = offset;
			paint.beginPath();
			paint.strokeStyle = GestiConfig.theme.buttonIconColor;
			paint.lineWidth = 1;
			paint.moveTo(0 * scale + offsetx, 0 * scale + offsety);
			paint.lineTo(10 * scale + offsetx, 10 * scale + offsety);
			paint.moveTo(10 * scale + offsetx, 0 * scale + offsety);
			paint.lineTo(0 * scale + offsetx, 10 * scale + offsety);
			paint.stroke();
			paint.closePath();
		}
		/**
		 * @description 上锁中
		 * @param paint
		 * @param offset
		 */
		static drawLock(paint, offset) {
			const {
				offsetx,
				offsety
			} = offset;
			paint.beginPath();
			paint.strokeStyle = GestiConfig.theme.buttonIconColor;
			paint.lineWidth = 1;
			paint.arc(5 + offsetx, offsety + 3, 3, Math.PI, 0);
			paint.strokeRect(offsetx, offsety + 4, 10, 6);
			paint.strokeRect(offsetx + 4, offsety + 6, 2, 2);
			paint.stroke();
			paint.closePath();
		}
		/**
		 * @description 解锁状态
		 * @param paint
		 * @param offset
		 */
		static drawDeLock(paint, offset) {
			const {
				offsetx,
				offsety
			} = offset;
			paint.beginPath();
			paint.strokeStyle = GestiConfig.theme.buttonIconColor;
			paint.lineWidth = 1;
			paint.arc(5 + offsetx, offsety + 2, 3, Math.PI, 0);
			paint.strokeRect(offsetx, offsety + 6, 10, 6);
			paint.strokeRect(offsetx + 4, offsety + 7, 2, 2);
			paint.stroke();
			paint.closePath();
		}
		/**
		 * @description 改变宽度或者高度，不是等比例缩放
		 * @param paint
		 * @param offset
		 */
		static drawChangeSizeAlone(paint, offset) {
			const {
				offsetx: x,
				offsety: y
			} = offset;
			paint.beginPath();
			paint.fillStyle = GestiConfig.theme.buttonIconColor;
			paint.arc(x, y, 3, 0, Math.PI * 2);
			paint.fill();
			paint.closePath();
		}
	}
	//预设竖线，后使用importAll导入即可
	Widgets.verticalLine =
		'{"viewObjType":"write","options":{"config":{"type":"line","lineWidth":3,"color":"black","isFill":false,"scaleX":1,"scaleY":1},"points":[{"x":-175,"y":0},{"x":175,"y":0}],"rect":{"x":275,"y":298,"width":351,"height":30,"angle":-1.576494270827876},"relativeRect":{"x":0,"y":0,"width":351,"height":30,"angle":-1.576494270827876},"mirror":false,"locked":false}}';
	//预设横线
	Widgets.horizonLine =
		'{"viewObjType":"write","options":{"config":{"type":"line","lineWidth":3,"color":"black","isFill":false,"scaleX":1,"scaleY":1},"points":[{"x":-144,"y":0},{"x":144,"y":0}],"rect":{"x":244,"y":549,"width":289,"height":30,"angle":-0.006920304750240513},"relativeRect":{"x":0,"y":0,"width":289,"height":30,"angle":-0.006920304750240513},"mirror":false,"locked":false}}';
	//预设矩形
	Widgets.rect =
		'{"viewObjType":"write","options":{"config":{"type":"rect","color":"black","lineWidth":1,"isFill":false,"scaleX":1,"scaleY":1},"points":[{"x":-115,"y":-74},{"x":115,"y":-74},{"x":115,"y":74},{"x":-115,"y":74}],"rect":{"x":299,"y":355,"width":231,"height":148,"angle":0},"relativeRect":{"x":0,"y":0,"width":231,"height":148,"angle":0},"mirror":false,"locked":false}}';
	//预设源泉
	Widgets.circle =
		'{"viewObjType":"write","options":{"config":{"type":"circle","color":"black","lineWidth":1,"isFill":false,"scaleX":1,"scaleY":1},"points":[{"x":-78,"y":-57},{"x":78,"y":57}],"rect":{"x":297,"y":342,"width":157,"height":114,"angle":0},"relativeRect":{"x":0,"y":0,"width":157,"height":114,"angle":0},"mirror":false,"locked":false}}';

	class CloseButton extends Button {
		constructor(master) {
			super(master);
			this.trigger = FuncButtonTrigger.click;
			this.radius = 10;
			this.init({
				percentage: [.5, -.5]
			});
		}
		updatePosition(vector) {
			this.updateRelativePosition();
			this.setAbsolutePosition(vector);
		}
		setMaster(master) {
			this.master = master;
		}
		effect() {
			this.master.hide();
		}
		draw(paint) {
			const {
				width,
				height
			} = this.master.rect.size;
			const halfRadius = this.radius * .75;
			const x = this.relativeRect.position.x,
				y = this.relativeRect.position.y;
			paint.beginPath();
			paint.fillStyle = GestiConfig.theme.buttonsBgColor;
			paint.arc(x, y, this.radius, 0, Math.PI * 2);
			paint.closePath();
			paint.fill();
			Widgets.drawClose(paint, {
				offsetx: x - halfRadius + 4,
				offsety: -height / 2 - 3
			});
		}
		update(paint) {
			this.draw(paint);
		}
		onSelected() {}
	}

	class DragButton extends Button {
		constructor(master, options) {
			var _a;
			super(master);
			this.trigger = FuncButtonTrigger.drag;
			this.oldViewObjectRect = null;
			this.oldRadius = 0;
			this.oldAngle = 0;
			this.radius = 10;
			this.disable = false;
			//拉伸变化方式  比例   水平  垂直   自由
			this.axis = "ratio";
			this.key = +new Date();
			this.init({
				percentage: [.5, .5]
			});
			this.initScale();
			this.rect.onDrag = (newRect) => {
				/*拖拽缩放*/
				this.rect = newRect;
				this.effect(newRect);
			};
			if (options)
				this.axis = (_a = options.axis) !== null && _a !== void 0 ? _a : "ratio";
		}
		updatePosition(vector) {
			this.updateRelativePosition();
			this.setAbsolutePosition(vector);
		}
		setAxis(axis) {
			this.axis = axis;
		}
		setMaster(master) {
			this.master = master;
		}
		/**
		 * 为拖拽改变大小初始化
		 */
		initScale() {
			this.setRelativePositionRect(this.options.percentage);
			this.oldRadius = Vector.mag(this.relativeRect.position);
		}
		effect(newRect) {
			/**
			 * @param {ImageRect} newRect 新的万向点Rect三个月还有
			 * @description 万向点的坐标是基于 @ViewObject 内的Rect @ImageRect 的，所以得到的一直是相对坐标
			 */
			const oldRect = this.oldViewObjectRect;
			const offsetx = newRect.position.x - oldRect.position.x,
				offsety = newRect.position.y - oldRect.position.y;
			/*等比例缩放*/
			const scale = Vector.mag(new Vector(offsetx, offsety)) / this.oldRadius;
			/*不适用于scale函数，需要基于原大小改变*/
			let newWidth = ~~(oldRect.size.width * scale),
				newHeight = ~~(oldRect.size.height * scale);
			if (this.axis == "horizontal") {
				newHeight = ~~(oldRect.size.height * 1);
			} else if (this.axis == "vertical") {
				newWidth = ~~(oldRect.size.width * 1);
			} else if (this.axis == "ratio");
			else if (this.axis == "free") {
				newWidth = oldRect.size.width * (offsetx * 1.5 / this.oldRadius);
				newHeight = oldRect.size.height * (offsety * 1.5 / this.oldRadius);
			}
			this.master.rect.setSize(newWidth, newHeight, true);
			/*this.oldAngle为弧度，偏移量*/
			const angle = Math.atan2(offsety, offsetx) - this.oldAngle;
			if (this.axis == "ratio")
				this.master.rect.setAngle(angle, true);
			this.master.rect.setScale(scale, false);
		}
		get getOldAngle() {
			return this.oldAngle;
		}
		update(paint) {
			this.draw(paint);
		}
		onSelected() {
			this.oldViewObjectRect = this.master.rect.copy();
			this.initScale();
		}
		hide() {
			this.disable = true;
		}
		show() {
			this.disable = false;
		}
		draw(paint) {
			if (this.disable)
				return;
			const halfRadius = this.radius * .75;
			const x = this.relativeRect.position.x,
				y = this.relativeRect.position.y;
			paint.beginPath();
			paint.fillStyle = GestiConfig.theme.buttonsBgColor;
			paint.arc(x, y, this.radius, 0, Math.PI * 2);
			paint.closePath();
			paint.fill();
			Widgets.drawGrag(paint, {
				offsetx: x - halfRadius + 2,
				offsety: y - halfRadius + 2
			});
		}
	}

	class MirrorButton extends Button {
		constructor(master) {
			super(master);
			this.trigger = FuncButtonTrigger.click;
			this.radius = 10;
			this.init({
				percentage: [-.5, .5]
			});
		}
		/**
		 * @description 相对坐标为以父对象为原点的定位
		 * 绝对坐标是以canvas为原点的定位
		 * 相对坐标用于渲染
		 * 绝对坐标用于事件捕获
		 * 相对坐标一般会直接以父对象为原点进行设置数据
		 * 绝对坐标一般需要参考父对象进行设置数据  绝对坐标等于 = 父.绝对+ 相对
		 * 绝对.x=父绝对+cos(θ+初始定位θ)*父半径
		 * @param vector
		 */
		updatePosition(vector) {
			// this.setRelativePosition([-.5,.5]);
			//this.setAbsolutePosition(vector);
			this.updateRelativePosition();
			this.setAbsolutePosition(vector);
		}
		setMaster(master) {
			this.master = master;
		}
		effect() {
			this.master.mirror();
		}
		draw(paint) {
			const {
				width,
				height
			} = this.master.rect.size;
			const halfRadius = this.radius * .75;
			const x = this.relativeRect.position.x,
				y = this.relativeRect.position.y;
			paint.beginPath();
			paint.fillStyle = GestiConfig.theme.buttonsBgColor;
			paint.arc(x, y, this.radius, 0, Math.PI * 2);
			paint.closePath();
			paint.fill();
			Widgets.drawMirror(paint, {
				offsetx: x - halfRadius + 1,
				offsety: height / 2 - halfRadius + 3
			});
		}
		update(paint) {
			this.draw(paint);
		}
		onSelected() {}
	}

	class RotateButton extends Button {
		constructor(master) {
			super(master);
			this.trigger = FuncButtonTrigger.drag;
			this.oldViewObjectRect = null;
			this.oldRadius = 0;
			this.oldAngle = 0;
			this.radius = 10;
			this.disable = false;
			this.key = +new Date();
			this.name = "rotate";
			this.init({
				position: new Vector(0, (master.rect.size.height >> 1) + 10),
			});
			this.initScale();
			this.rect.onDrag = (newRect) => {
				/*拖拽缩放*/
				this.rect = newRect;
				this.effect(newRect);
			};
		}
		updatePosition(vector) {
			this.updateRelativePosition();
			this.setAbsolutePosition(vector);
		}
		setMaster(master) {
			this.master = master;
		}
		/**
		 * 为拖拽改变大小初始化
		 */
		initScale() {
			this.oldRadius = Vector.mag(this.relativeRect.position);
		}
		effect(newRect) {
			/**
			 * @param {ImageRect} newRect 新的万向点Rect三个月还有
			 * @description 万向点的坐标是基于 @ViewObject 内的Rect @ImageRect 的，所以得到的一直是相对坐标
			 */
			const oldRect = this.oldViewObjectRect;
			const offsetx = newRect.position.x - oldRect.position.x,
				offsety = newRect.position.y - oldRect.position.y;
			let angle = Math.atan2(offsety, offsetx) - this.oldAngle;
			//辅助旋转
			{
				let _angle = +angle.toFixed(2);
				const _45 = 0.78;
				const limit = 0.1;
				const scale = (angle / 0.78) >> 0;
				angle = Math.abs(_angle - scale * _45) < limit ? scale * _45 : _angle;
			}
			this.master.rect.setAngle(angle);
		}
		get getOldAngle() {
			return this.oldAngle;
		}
		update(paint) {
			this.draw(paint);
		}
		onSelected() {
			this.oldViewObjectRect = this.master.rect.copy();
			this.initScale();
		}
		hide() {
			this.disable = true;
		}
		show() {
			this.disable = false;
		}
		draw(paint) {
			if (this.disable)
				return;
			const x = this.relativeRect.position.x,
				y = this.relativeRect.position.y;
			paint.beginPath();
			paint.fillStyle = GestiConfig.theme.buttonsBgColor;
			paint.arc(x, y, this.radius, 0, Math.PI * 2);
			paint.closePath();
			paint.fill();
			Widgets.drawRotate(paint, {
				offsetx: x,
				offsety: y,
			});
		}
	}

	class UnLockButton extends Button {
		constructor(master) {
			super(master);
			this.trigger = FuncButtonTrigger.click;
			this.radius = 10;
			this.init({
				percentage: [.5, .5],
			});
			this.free = true;
			this.disabled = true;
		}
		updatePosition(vector) {
			this.updateRelativePosition();
			this.setAbsolutePosition(vector);
		}
		setMaster(master) {
			this.master = master;
		}
		effect() {
			this.master.unLock();
		}
		draw(paint) {
			this.master.rect.size;
			const halfRadius = this.radius * .75;
			const x = this.relativeRect.position.x,
				y = this.relativeRect.position.y;
			paint.beginPath();
			paint.fillStyle = GestiConfig.theme.buttonsBgColor;
			paint.arc(x, y, this.radius, 0, Math.PI * 2);
			paint.closePath();
			paint.fill();
			Widgets.drawDeLock(paint, {
				offsetx: x - halfRadius + 2,
				offsety: y - halfRadius + 2
			});
		}
		update(paint) {
			this.draw(paint);
		}
		onSelected() {}
	}

	class HorizonButton extends DragButton {
		constructor(master) {
			super(master);
		}
		draw(paint) {
			this.setAxis("horizontal");
			this.init({
				percentage: [0.55, 0]
			});
			//按钮渲染样式
			this.draw = function(paint) {
				const {
					x,
					y
				} = this.relativeRect.position;
				Widgets.drawChangeSizeAlone(paint, {
					offsetx: x,
					offsety: y,
				});
			};
		}
	}

	class LockButton extends Button {
		constructor(master) {
			super(master);
			this.trigger = FuncButtonTrigger.click;
			this.radius = 10;
			this.init({
				percentage: [-.5, -.5]
			});
		}
		updatePosition(vector) {
			this.updateRelativePosition();
			this.setAbsolutePosition(vector);
		}
		setMaster(master) {
			this.master = master;
		}
		effect() {
			this.master.lock();
		}
		draw(paint) {
			const {
				width,
				height
			} = this.master.rect.size;
			const halfRadius = this.radius * .75;
			const x = this.relativeRect.position.x,
				y = this.relativeRect.position.y;
			paint.beginPath();
			paint.fillStyle = GestiConfig.theme.buttonsBgColor;
			paint.arc(x, y, this.radius, 0, Math.PI * 2);
			paint.closePath();
			paint.fill();
			Widgets.drawLock(paint, {
				offsetx: x - halfRadius + 1,
				offsety: -height / 2 - halfRadius + 3
			});
		}
		update(paint) {
			this.draw(paint);
		}
		onSelected() {}
	}

	class VerticalButton extends DragButton {
		constructor(master) {
			super(master);
		}
		draw(paint) {
			this.setAxis("vertical");
			this.init({
				percentage: [0, -.6]
			});
			//按钮渲染样式
			this.draw = function(paint) {
				const {
					x,
					y
				} = this.relativeRect.position;
				Widgets.drawChangeSizeAlone(paint, {
					offsetx: x,
					offsety: y,
				});
			};
		}
	}

	class CanvasConfig {
		init(kit) {
			this.kit = kit;
		}
		get rect() {
			return this.kit.getCanvasRect;
		}
		//所有图层对象
		get views() {
			return this.kit.getViewObjects;
		}
		setGlobalPaint(paint) {
			this.paint = paint;
		}
		get globalPaint() {
			return this.paint;
		}
	}
	var canvasConfig = new CanvasConfig();

	function __awaiter(thisArg, _arguments, P, generator) {
		function adopt(value) {
			return value instanceof P ? value : new P(function(resolve) {
				resolve(value);
			});
		}
		return new(P || (P = Promise))(function(resolve, reject) {
			function fulfilled(value) {
				try {
					step(generator.next(value));
				} catch (e) {
					reject(e);
				}
			}

			function rejected(value) {
				try {
					step(generator["throw"](value));
				} catch (e) {
					reject(e);
				}
			}

			function step(result) {
				result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
			}
			step((generator = generator.apply(thisArg, _arguments || [])).next());
		});
	}

	function __values(o) {
		var s = typeof Symbol === "function" && Symbol.iterator,
			m = s && o[s],
			i = 0;
		if (m) return m.call(o);
		if (o && typeof o.length === "number") return {
			next: function() {
				if (o && i >= o.length) o = void 0;
				return {
					value: o && o[i++],
					done: !o
				};
			}
		};
		throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
	}

	function __asyncValues(o) {
		if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
		var m = o[Symbol.asyncIterator],
			i;
		return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](),
			i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function() {
				return this;
			}, i);

		function verb(n) {
			i[n] = o[n] && function(v) {
				return new Promise(function(resolve, reject) {
					v = o[n](v), settle(resolve, reject, v.done, v.value);
				});
			};
		}

		function settle(resolve, reject, d, v) {
			Promise.resolve(v).then(function(v) {
				resolve({
					value: v,
					done: d
				});
			}, reject);
		}
	}

	class XImage {
		/**
       *   interface createImageOptions {
              data?: HTMLImageElement | SVGImageElement | HTMLVideoElement | HTMLCanvasElement | Blob | ImageData | ImageBitmap | OffscreenCanvas, options?: createImageOptions,
              width?: number,
              height?: number,
              scale?: number,
              maxScale?: number,
              minScale?: number,
          }
       *
       */
		constructor(params) {
			this.width = 0;
			this.height = 0;
			this.x = 0;
			this.y = 0;
			this.scale = 1;
			this.isImageData = false
			const {
				data,
				width,
				height,
				scale,
				originData,
				isImageData,
			} = params;
			if (!data || !width || !height)
				throw Error("数据或宽或高不能为空");
			this.originData = originData;
			this.data = data;
			this.width = width;
			this.height = height;
			this.scale = scale || 1;
			this.fixedWidth = width;
			this.fixedHeight = height;
			this.width *= this.scale;
			this.height *= this.scale;
			this.width = ~~this.width;
			this.height = ~~this.height;
			this.isImageData = isImageData;
			console.log("是否", this.isImageData)
		}
		toJson() {
			return {
				x: this.x,
				y: this.y,
				width: this.width,
				height: this.height,
			};
		}
	}

	class GesteControllerImpl {
		constructor(kit) {
			//使用控制器时，取消原有控制
			this.kit = kit;
		}
		destroyGesti() {
			this.kit.destroyGesti();
		}
		removeListener(listenType, hook) {
			this.kit.removeListener(listenType, hook);
		}
		load(view) {
			return this.kit.load(view);
		}
		select(select) {
			return this.kit.select(select);
		}
		get currentViewObject() {
			return this.kit.currentViewObject;
		}
		rotate(angle, existing, view) {
			return this.kit.rotate(angle, existing, view);
		}
		upward(viewObject) {
			return this.kit.upward(viewObject);
		}
		downward(viewObject) {
			return this.kit.downward(viewObject);
		}
		leftward(viewObject) {
			return this.kit.leftward(viewObject);
		}
		rightward(viewObject) {
			return this.kit.rightward(viewObject);
		}
		importAll(json, weChatCanvas) {
			return this.kit.importAll(json, weChatCanvas);
		}
		exportAll(offScreenPainter) {
			return this.kit.exportAll(offScreenPainter);
		}
		addWrite(options) {
			return this.kit.addWrite(options);
		}
		addListener(listenType, callback, prepend) {
			return this.kit.addListener(listenType, callback, prepend);
		}
		updateText(text, options) {
			this.kit.updateText(text, options);
		}
		center(axis, view) {
			this.kit.center(axis, view);
		}
		addText(text, options) {
			return this.kit.addText(text, options);
		}
		cancel(view) {
			this.kit.cancel(view);
		}
		cancelAll() {
			this.kit.cancelAll();
		}
		layerLower(view) {
			this.kit.layerLower(view);
		}
		layerRise(view) {
			this.kit.layerRise(view);
		}
		layerTop(view) {
			this.kit.layerTop(view);
		}
		layerBottom(view) {
			this.kit.layerBottom(view);
		}
		update() {
			this.kit.update();
		}
		cancelEvent() {
			this.kit.cancelEvent();
		}
		unLock(view) {
			this.kit.unLock(view);
		}
		lock(view) {
			this.kit.lock(view);
		}
		fallback() {
			this.kit.fallback();
		}
		cancelFallback() {
			this.kit.cancelFallback();
		}
		/**
		 * @param {Event} e
		 * @description  点击
		 * @public
		 */
		down(e) {
			this.eventTransForm(e, this.kit.onDown);
		}
		/**
		 * @param {Event} e
		 * @description 移动
		 * @public
		 */
		move(e) {
			this.eventTransForm(e, this.kit.onMove);
		}
		/**
		 * @param {Event} e
		 * @description 抬起
		 * @public
		 */
		up(e) {
			this.eventTransForm(e, this.kit.onUp, "changedTouches");
		}
		/**
		 * @param {Event} e
		 * @description 鼠标滚轮
		 * @public
		 */
		wheel(e) {
			//只有Pc端有
			if ("touches" in e)
				return;
			this.kit.onWheel.bind(this.kit)(e);
		}
		/**
		 * @param {Event} e
		 * @param {Function} callback
		 * @description 判断是移动端还是Pc端
		 * @private
		 */
		eventTransForm(e, callback, key) {
			if ("touches" in e) {
				//移动端
				/**
				 * 移动端分为 browser 和 微信
				 * 微信内没有clientX，而是 x
				 */
				return this.action(e, callback, key || "");
			} else if ("clientX" in e) {
				//pc端
				const {
					clientX: x,
					clientY: y
				} = e;
				const vector = new Vector(x, y);
				return callback.bind(this.kit)(vector);
			}
		}
		/**
		 * @param {Array<Event>} touches
		 * @return Array<Vector>
		 */
		twoFingers(touches) {
			const e1 = touches[0];
			const e2 = touches[1];
			const vector1 = new Vector(e1.clientX || e1.x, e1.clientY || e1.y);
			const vector2 = new Vector(e2.clientX || e2.x, e2.clientY || e2.y);
			return [vector1, vector2];
		}
		/**
		 * @param {Event} _e
		 * @param {Function} callback
		 * @description 移动端分为微信和browser
		 * @private
		 */
		action(_e, callback, key) {
			/**
			 * 点击和移动事件 三个都有
			 * 抬起事件只有changedTouches
			 * 针对Up事件，提供以下针对方案
			 */
			const touches = key ?
				_e[key] :
				_e.touches || _e.targetTouches || _e.changedTouches;
			if (touches.length >= 2) {
				callback.bind(this.kit)(this.twoFingers(touches));
			} else {
				const e = touches[0];
				const vector = new Vector(e.clientX || e.x, e.clientY || e.y);
				callback.bind(this.kit)(vector);
			}
		}
		addImage(ximage) {
			return __awaiter(this, void 0, void 0, function*() {
				if (ximage.constructor.name == "Promise") {
					const _ximage = yield ximage;
					return this.kit.addImage(_ximage);
				}
				//使用any类型强制转换
				const _ximage = ximage;
				return this.kit.addImage(_ximage);
			});
		}
		/**
		 * @description 根据传入的image生成一个 @ImageBitmap 实例，拿到图片的宽高数据，创建XImage对象
		 * @param image
		 * @param options
		 * @returns Promise< @XImage >
		 */
		createImage(image, options) {
			return new Promise((r, e) => __awaiter(this, void 0, void 0, function*() {
				try {
					const bimp = yield createImageBitmap(image);
					const {
						width,
						height
					} = bimp;
					const ximage = new XImage({
						data: bimp,
						originData: image,
						width: (options === null || options === void 0 ? void 0 :
							options.width) || width,
						height: (options === null || options === void 0 ? void 0 :
							options.height) || height,
						scale: (options === null || options === void 0 ? void 0 :
							options.scale) || 1,
						maxScale: (options === null || options === void 0 ? void 0 :
							options.maxScale) || 10,
						minScale: (options === null || options === void 0 ? void 0 :
							options.minScale) || 0.1,
					});
					r(ximage);
				} catch (error) {
					r(error);
				}
			}));
		}
	}

	class Drag {
		constructor() {
			this.rect = null;
		}
		catchViewObject(rect, position) {
			this.rect = rect;
			this.offset = new Vector(this.rect.position.x - position.x, this.rect.position.y - position
				.y);
		}
		cancel() {
			this.rect = null;
		}
		update(position) {
			if (this.rect == null)
				return;
			if (this.rect.beforeDrag != null)
				this.rect.beforeDrag(this.rect);
			position.add(this.offset);
			this.rect.position = position;
			if (this.rect.onDrag != null)
				this.rect.onDrag(this.rect);
		}
	}

	class GestiEventManager {
		getEvent(kit) {
			if (typeof(window) != "undefined") {
				const isMobile = /Mobile/.test(navigator.userAgent);
				if (isMobile)
					return new GestiTouchEvent(kit);
				return new GestiMouseEvent(kit);
			} else if (typeof(wx) != "undefined") {
				return null;
			}
			return new GestiTouchEvent(kit);
		}
	}
	class GestiTouchEvent {
		constructor(kit) {
			this.disabled = false;
			this.kit = kit;
		}
		disable() {
			this.disabled = true;
		}
		twoFingers(touches) {
			const e1 = touches[0];
			const e2 = touches[1];
			const vector1 = new Vector(e1.clientX, e1.clientY);
			const vector2 = new Vector(e2.clientX, e2.clientY);
			return [vector1, vector2];
		}
		down(down) {
			window.addEventListener('touchstart', (_e) => {
				if (this.disabled)
					return;
				const touches = _e.targetTouches;
				if (touches.length >= 2) {
					down.bind(this.kit)(this.twoFingers(touches));
				} else {
					const e = touches[0];
					const vector = new Vector(e.clientX, e.clientY);
					down.bind(this.kit)(vector);
				}
			});
			return this;
		}
		up(up) {
			window.addEventListener('touchend', (_e) => {
				if (this.disabled)
					return;
				const e = _e.changedTouches[0];
				const vector = new Vector(e.clientX, e.clientY);
				up.bind(this.kit)(vector);
			});
			return this;
		}
		move(move) {
			window.addEventListener('touchmove', (_e) => {
				if (this.disabled)
					return;
				const touches = _e.targetTouches;
				if (touches.length >= 2) {
					move.bind(this.kit)(this.twoFingers(touches));
				} else {
					const e = touches[0];
					const vector = new Vector(e.clientX, e.clientY);
					move.bind(this.kit)(vector);
				}
			});
			return this;
		}
		wheel(whell) {
			//手机端不用适配
		}
	}
	class GestiMouseEvent {
		constructor(kit) {
			this.disabled = false;
			this.kit = kit;
		}
		disable() {
			this.disabled = true;
		}
		twoFingers(touches) {
			return [];
		}
		down(down) {
			window.addEventListener('mousedown', (e) => {
				const vector = new Vector(e.clientX, e.clientY);
				if (this.disabled)
					return;
				down.bind(this.kit)(vector);
			});
			return this;
		}
		up(up) {
			window.addEventListener('mouseup', (e) => {
				const vector = new Vector(e.clientX, e.clientY);
				if (this.disabled)
					return;
				up.bind(this.kit)(vector);
			});
			return this;
		}
		move(move) {
			window.addEventListener('mousemove', (e) => {
				const vector = new Vector(e.clientX, e.clientY);
				if (this.disabled)
					return;
				move.bind(this.kit)(vector);
			});
			return this;
		}
		wheel(wheel) {
			window.addEventListener('wheel', (e) => {
				wheel.bind(this.kit)(e);
			});
		}
	}

	/**
	 * 二指操作类
	 */
	class TwoFingerOperate {
		constructor() {
			this.ViewObject = null;
			this.oldRect = null;
			this.oldDist = 0;
			this.oldAngle = -1;
		}
		onStart(ViewObject, start) {
			this.ViewObject = ViewObject;
			this.oldRect = this.ViewObject.rect.copy();
			this.start = start;
			/**
			 * 解构得到两个 @Vector ,算出它们的距离，并赋值给 @oldDist
			 */
			const [a, b] = this.start;
			this.oldDist = Vector.dist(a, b);
			const v = Vector.sub(a, b);
			this.oldAngle = Math.atan2(v.y, v.x) - this.ViewObject.rect.getAngle;
		}
		cancel() {
			this.ViewObject = null;
			this.oldRect = null;
		}
		update(positions) {
			if (this.ViewObject == null)
				return;
			const [a, b] = positions;
			const dist = Vector.dist(a, b);
			const scale = dist / this.oldDist;
			const newWidth = this.oldRect.size.width * scale,
				newHeight = this.oldRect.size.height * scale;
			this.ViewObject.rect.setSize(newWidth, newHeight);
			const v = Vector.sub(a, b);
			const angle = Math.atan2(v.y, v.x) - this.oldAngle;
			this.ViewObject.rect.setAngle(angle);
		}
	}
	/**
	 * 该类为手势判断类
	 * 点击
	 * 抬起
	 * 滑动
	 * 双击
	 * 长按
	 *
	 * ！！！ 双击和长按等手势只支持单指
	 * ！！！待优化，单击和双击存在竞争问题
	 */
	class Gesture {
		constructor() {
			//判断长按事件，间隔时长
			this.longPressTimeout = 1000;
			//双击间隔时长
			this.dbClickTimeout = 200;
			this.clickTimeout = 200;
			//按下屏幕的时间
			this.pressTime = 0;
			//down的时间，不包括move
			this.downTime = 0;
			//抬起屏幕的时间
			this.upTime = 0;
			//抬起屏幕的时间
			this.preUpTime = 0;
			this.clickEventList = new Array();
			this.dbclickEventList = new Array();
			this.longpressEventList = new Array();
			this.twoTouchEventList = new Array();
			this.globalClickEventList = [];
			this.globalDownEventList = [];
			this.operate = null;
		}
		isTwoFingers(touches) {
			if (Array.isArray(touches) && touches.length == 2)
				return true;
			return false;
		}
		onUp(ViewObject, position) {
			if (!Array.isArray(position)) {
				this.endPosition = position;
			}
			this.preUpTime = this.upTime;
			this.upTime = +new Date();
			if (this.isClick) {
				this.onGlobalClick(position);
			}
			if (ViewObject == null)
				return;
			const _position = position;
			this.upVector = _position;
			//判断长按
			if (this.isLonePress) {
				this.onLonePress(ViewObject, position);
			} else if (this.isDbClick) {
				this.onDbClick(ViewObject, position);
			} else if (this.endPosition.equals(this.startPosition)) {
				this.onClick(ViewObject, position);
			}
		}
		onMove(ViewObject, position) {
			this.pressTime = +new Date();
			if (ViewObject == null)
				return;
			const vector = position;
			this.update(vector);
		}
		onDown(ViewObject, position) {
			if (!Array.isArray(position)) {
				this.startPosition = position;
			}
			this.downTime = +new Date();
			this.pressTime = +new Date();
			if (ViewObject == null)
				return;
			const _position = position;
			this.pressVector = _position;
			if (this.isTwoFingers(position)) {
				this.onTwoFingers(ViewObject, position);
			}
		}
		get isLonePress() {
			if (this.upTime - this.pressTime > this.longPressTimeout)
				return true;
			return false;
		}
		get isDbClick() {
			return this.upTime - this.preUpTime < this.dbClickTimeout;
		}
		get isClick() {
			return this.upTime - this.downTime <= this.clickTimeout;
		}
		/**
		 * 二指操作
		 * @param ViewObject
		 * @param start
		 */
		onTwoFingers(ViewObject, position) {
			this.operate = new TwoFingerOperate();
			this.operate.onStart(ViewObject, position);
			this.twoTouchEventList.forEach((listenCallback) => {
				listenCallback(ViewObject, position);
			});
		}
		/**
		 * @description 长按操作
		 * @param ViewObject
		 * @param start
		 */
		onLonePress(ViewObject, position) {
			this.longpressEventList.forEach((listenCallback) => {
				listenCallback(ViewObject, position);
			});
		}
		onDbClick(ViewObject, position) {
			this.dbclickEventList.forEach((listenCallback) => {
				listenCallback(ViewObject, position);
			});
		}
		onClick(ViewObject, position) {
			this.clickEventList.forEach((listenCallback) => {
				listenCallback(ViewObject, position);
			});
		}
		onGlobalClick(position) {
			this.globalClickEventList.forEach(eventCallback => {
				eventCallback(position);
			});
		}
		/**
		 * @description 添加监听事件
		 * @param gestiType
		 * @param listenCallback
		 */
		addListenGesti(gestiType, listenCallback) {
			if (gestiType === 'click')
				this.clickEventList.push(listenCallback);
			if (gestiType === 'longpress')
				this.longpressEventList.push(listenCallback);
			if (gestiType === 'dbclick')
				this.dbclickEventList.push(listenCallback);
			if (gestiType === "twotouch")
				this.twoTouchEventList.push(listenCallback);
			if (gestiType === 'globalClick')
				this.globalClickEventList.push(listenCallback);
		}
		cancel() {
			if (this.operate == null)
				return;
			this.operate.cancel();
		}
		update(positions) {
			if (this.operate == null)
				return;
			this.operate.update(positions);
		}
	}

	/*
	    使用代理模式重写Painter，兼容原生Painter
	*/
	class Painter {
		constructor(paint) {
			this.paint = null;
			this.paint = paint;
		}
		//仅限window
		get canvas() {
			if (typeof window != "undefined")
				return this.paint.canvas;
			return undefined;
		}
		set fillStyle(style) {
			this.paint.fillStyle = style;
		}
		set lineWidth(width) {
			this.paint.lineWidth = width;
		}
		set strokeStyle(style) {
			this.paint.strokeStyle = style;
		}
		set textBaseLine(baseLine) {
			if (this.paint.textBaseline)
				this.paint.textBaseline = baseLine;
		}
		draw() {
			var _a, _b;
			(_b = (_a = this.paint) === null || _a === void 0 ? void 0 : _a.draw) === null || _b ===
				void 0 ? void 0 : _b.call(this.paint);
		}
		strokeRect(x, y, w, h) {
			this.paint.strokeRect(x, y, w, h);
		}
		fillRect(x, y, w, h) {
			this.paint.fillRect(x, y, w, h);
		}
		stroke() {
			this.paint.stroke();
		}
		clearRect(x, y, w, h) {
			if (typeof uni != "undefined" && this.paint.draw)
				this.draw();
			else
				this.paint.clearRect(x, y, w, h);
		}
		save() {
			this.paint.save();
		}
		rotate(angle) {
			this.paint.rotate(angle);
		}
		beginPath() {
			this.paint.beginPath();
		}
		closePath() {
			this.paint.closePath();
		}
		restore() {
			this.paint.restore();
		}
		translate(x, y) {
			this.paint.translate(x, y);
		}
		fill() {
			this.paint.fill();
		}
		arc(x, y, radius, start, end) {
			this.paint.arc(x, y, radius, start, end);
		}
		arcTo(x1, y1, x2, y2, radius) {
			this.paint.arcTo(x1, y1, x2, y2, radius);
		}
		/**
		 *
		 * @param x 圆心点x
		 * @param y 圆心点y
		 * @param a width
		 * @param b height
		 */
		ellipse(x, y, a, b) {
			this.paint.save();
			this.paint.translate(x, y);
			const r = a > b ? a : b;
			const rx = a / r,
				ry = b / r;
			this.paint.scale(rx, ry);
			this.paint.beginPath();
			this.paint.arc(0, 0, r, 0, 2 * Math.PI);
			this.paint.closePath();
			this.paint.restore();
		}
		drawImage(image, x, y, width, height, dx, dy, dw, dh) {
			if (dx && dy) {
				this.paint.drawImage(image, -width / 2, -height / 2, width, height, dx, dy, dw, dh);
			} else {
				this.paint.drawImage(image, -width / 2, -height / 2, width, height);
			}
		}
		scale(a, b) {
			this.paint.scale(a, b);
		}
		moveTo(x, y) {
			this.paint.moveTo(x, y);
		}
		lineTo(x, y) {
			this.paint.lineTo(x, y);
		}
		getImageData(x, y, w, h) {
			return new Promise((reslove, j) => {
				reslove(this.paint.getImageData(x, y, w, h));
			});
		}
		fillText(text, x, y) {
			this.paint.fillText(text, x, y);
		}
		strokeText(text, x, y, maxWidth) {
			this.paint.strokeText(text, x, y, maxWidth);
		}
		set font(font) {
			this.paint.font = font;
		}
		measureText(text) {
			var _a;
			return (_a = this.paint) === null || _a === void 0 ? void 0 : _a.measureText(text);
		}
		set lineCap(lineCap) {
			this.paint.lineCap = lineCap;
		}
		set lineJoin(lineJoin) {
			this.paint.lineJoin = lineJoin;
		}
		quadraticCurveTo(cpx, cpy, x, y) {
			this.paint.quadraticCurveTo(cpx, cpy, x, y);
		}
		setlineDash(dash) {
			var _a;
			(_a = this.paint) === null || _a === void 0 ? void 0 : _a.setLineDash(dash);
		}
		putImageData(imageData, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight) {
			this.paint.putImageData(imageData, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight);
		}
		/*清空画布|刷新画布*/
		update() {}
	}

	const pako = require("pako");
	/**
	 * base64转换器
	 */
	class ImageChunkConverter {
		chunkToBase64(chunk) {
			const base64 = pako.gzip(chunk.imageData.data);
			chunk.base64 = base64;
			chunk.imageData = null;
			return chunk;
		}
		base64ToChunk(chunk, weChatCanvas) {
			const a = chunk;
			const arr = pako.inflate(a.base64);
			const imageData = weChatCanvas.createImageData(arr.length, a.width, a.height);
			imageData.data.set(arr);
			a.imageData = imageData;
			a.base64 = null;
			return a;
		}
		coverAllImageChunkToBase64(chunks) {
			const arr = chunks.map((item, ndx) => this.chunkToBase64(item));
			return arr;
		}
		/**
		 * @description chunks必须是数组类型json
		 * @param chunks
		 * @returns
		 */
		coverAllImageChunkBase64ToChunk(chunks) {
			const arr = chunks || [];
			return arr.map((item, ndx) => this.base64ToChunk(item));
		}
		customBtoa(input) {
			let result = '';
			let padding = 0;
			const base64Chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
			for (let i = 0; i < input.length; i += 3) {
				const a = input.charCodeAt(i);
				const b = input.charCodeAt(i + 1);
				const c = input.charCodeAt(i + 2);
				// Concatenate the bits of the three bytes into a single integer
				const combined = (a << 16) | (b << 8) | c;
				// Extract the base64 characters for each 6-bit chunk and add padding if needed
				result +=
					base64Chars[(combined >> 18) & 63] +
					base64Chars[(combined >> 12) & 63] +
					base64Chars[(combined >> 6) & 63] +
					base64Chars[combined & 63];
				// Keep track of how much padding is needed
				padding = input.length - i - 3;
			}
			// Add padding characters '=' based on how many bytes were in the original data
			if (padding === 1) {
				result = result.slice(0, -1) + '=';
			} else if (padding === 2) {
				result = result.slice(0, -2) + '==';
			}
			return result;
		}
		customAtob(input) {
			const base64Chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
			let result = '';
			const padding = input.endsWith('==') ? 2 : input.endsWith('=') ? 1 : 0;
			for (let i = 0; i < input.length; i += 4) {
				const chunk = (base64Chars.indexOf(input[i]) << 18) |
					(base64Chars.indexOf(input[i + 1]) << 12) |
					(base64Chars.indexOf(input[i + 2]) << 6) |
					base64Chars.indexOf(input[i + 3]);
				const bytes = [
					(chunk >> 16) & 0xff,
					(chunk >> 8) & 0xff,
					chunk & 0xff,
				].slice(0, 3 - padding);
				result += String.fromCharCode(...bytes);
			}
			return result;
		}
	}

	/**
	 * 图片切割
	 * 只做图片切割工作，其他不管
	 */
	class Cutter {
		/**
		 * @description offScreen为false时，你必须要传入一个painter对象
		 * @param offScreen
		 * @param painter
		 */
		constructor(offScreen, painter) {
			if (offScreen !== null && offScreen !== void 0 ? offScreen : true) {
				if (typeof OffscreenCanvas !== "undefined")
					//原生
					this.offScreenPainter = new OffscreenCanvas(10000, 10000).getContext("2d");
				else if (typeof wx !== "undefined") {
					//微信
					this.offScreenPainter = wx.createOffscreenCanvas({
						type: "2d",
						width: 10000,
						height: 10000,
					});
				} else if (typeof tt !== "undefined") {
					//抖音
					this.offScreenPainter = tt.createOffscreenCanvas({
						type: "2d",
						width: 10000,
						height: 10000,
					});
				} else {
					throw Error(
						"This platform does not have off-screen rendering function, please select painter"
					);
				}
			} else {
				if (!painter)
					throw Error(
						"When you give up off-screen rendering, you must pass in a painter object");
				this.painter = painter;
			}
		}
		/**
		 * @description 切割图片成小块
		 * @param chunkSize
		 * @param ximage
		 * @param offset
		 * @returns
		 */
		getChunks(chunkSize, ximage, offset) {
			return __awaiter(this, void 0, void 0, async function*() {
				const imgWidth = ximage.fixedWidth,
					imgHeight = ximage.fixedHeight;
				const g = this.offScreenPainter || this.painter;
				const _offset = offset || new Vector(0, 0);
				const chunks = [];
				const image = ximage.data;
				for (let y = 0; y < imgHeight; y += chunkSize) {
					//获取切割图片终点，预防临界点溢出
					const endY = Math.min(y + chunkSize, imgHeight);
					const height = endY - y;
					for (let x = 0; x < imgWidth; x += imgWidth) {
						const endX = Math.min(x + imgWidth, imgWidth);
						const width = endX - x;
						console.log(g.paint)
						g.clearRect(0, 0, imgWidth, chunkSize);
						// g.fillRect(x,y,width,height);
						console.log("要画", image)
						yield g.paint.drawImage(image, x, y, width,
							height, _offset.x, _offset.y, width, height);
							
						// g.fillRect(x,y,width,height)

						// ((g === null || g === void 0 ? void 0 : g.paint) ? g === null || g ===
						// 	void 0 ? void 0 : g.paint : g).drawImage(image, x, y, endX - x,
						// 	endY - y, _offset.x, _offset.y, endX - x, endY - y);
						
						
						const imageData = yield g.getImageData(_offset.x, _offset.y, width,
							height);
							
						// setTimeout(()=>{
						// 	console.log(g.getImageData(_offset.x, _offset.y, width,
						// 	height))
						// },1000);
						console.log("切片数据", imageData)
						chunks.push({
							x,
							y,
							width,
							height,
							imageData,
							base64: "",
						});
					}
				}
				return chunks;
			});
		}
		merge(width, height, chunks, weChatCanvas) {
			console.log("合并", chunks);
			console.log("宽高", width, height);
			this.offScreenPainter || this.painter;
			const coverter = new ImageChunkConverter();
			const imageData = weChatCanvas.createImageData([], width, height);
			//数组合并
			let curentNdx = 0;
			chunks.forEach((item) => {
				const chunk = coverter.base64ToChunk(item, weChatCanvas);
				console.log("片段", chunk)
				chunk.imageData.data.forEach((item) => {
					imageData.data[curentNdx++] = item;
				});
			});
			console.log("合并完成", imageData)
			return imageData;
		}
	}

	/**
	 * 辅助线显示
	 */
	class AuxiliaryLine {
		constructor() {
			//到距离5时参考线出现
			this.d = 3;
			//虚线
			this.dash = [3, 3];
			this.color = GestiConfig.theme.dashedLineColor;
			//参考点
			this.referencePoint = [];
		}
		createReferencePoint(key) {
			this.referencePoint = [];
			//获取画布内所有课操作对象
			const views = canvasConfig.views;
			//如果只有一个必定是自己
			if (views.length <= 1)
				return;
			views
				.filter((v) => v.key.toString() != key && !v.disabled)
				.forEach((view) => {
					var _a;
					view.rect;
					const position = view.rect.position;
					this.referencePoint.push(...((_a = view.getVertex()) !== null && _a !== void 0 ?
						_a : []));
					this.referencePoint.push(position);
				});
		}
		/**
		 * 遍历五个点
		 */
		getPoint(points) {
			const ps = [];
			for (let i = 0; i < points.length; i++) {
				const p = points[i];
				for (let j = 0; j < this.referencePoint.length; j++) {
					const rp = this.referencePoint[j];
					const item = {
						axis: "vertical",
						point: p,
						offset: new Vector(0, 0),
					};
					if (Math.abs(p.x - rp.x) < this.d || Math.abs(p.y - rp.y) < this.d) {
						if (Math.abs(p.x - rp.x) < this.d) {
							//y轴
							item.axis = "vertical";
							item.offset.x = p.x - rp.x;
						} else {
							//x轴
							item.axis = "horizon";
							item.offset.y = p.y - rp.y;
						}
						ps.push(item);
						break;
					}
				}
			}
			return ps.sort((a, b) => a.offset.x - b.offset.x);
		}
		draw(paint, view) {
			if (!view.rect.vertex)
				return;
			const dots = view.getVertex();
			const canvasRect = canvasConfig.rect;
			const canvasSize = canvasRect.size;
			view.rect.size;
			const position = view.rect.position;
			//中心点对应上下左右四个点
			new Vector(0, position.y).troweling();
			new Vector(position.x, 0).troweling();
			new Vector(canvasSize.width, position.y).troweling();
			new Vector(position.x, canvasSize.height).troweling();
			//上下左右四条辅助线
			const getLinePoint = (point, axis) => {
				if (axis == "horizon") {
					return [
						[new Vector(0, point.y), new Vector(canvasSize.width, point.y)],
					];
				} else {
					return [
						[new Vector(point.x, 0), new Vector(point.x, canvasSize.height)],
					];
				}
			};
			//临近点
			const lpoints = this.getPoint([...dots, position]);
			//上锁的对象不能被操作，对齐
			// if (lpoints.length != 0&&!view.isLock) {
			//   const offset = lpoints[0].offset;
			//   if (offset.x < 0) view.rect.position.add(offset);
			//   else view.rect.position.sub(offset);
			// }
			//得到线数据
			const lines = lpoints.map((item) => getLinePoint(item.point, item.axis));
			paint.beginPath();
			lines.forEach((ls) => {
				const [
					[p1, p2]
				] = ls;
				paint.moveTo(p1.x, p1.y);
				paint.lineTo(p2.x, p2.y);
			});
			paint.setlineDash(this.dash);
			paint.strokeStyle = this.color;
			paint.lineWidth = 1;
			paint.stroke();
			paint.closePath();
			paint.setlineDash([]);
		}
	}

	/**
	 * 凡是带有操作点的对象都是它，
	 * 例如 图片、文字 等
	 */
	class ViewObject extends OperationObserver {
		constructor() {
			super();
			this.selected = false;
			//矩形缩放时用到
			this.scale = 1;
			this.key = +new Date();
			this.isMirror = false;
			this.disabled = false;
			this.layer = 0;
			this.funcButton = new Array();
			/**
			 * @description 是否冻结锁住，
			 * 锁住过后可被选取，但是不能位移和改变大小
			 */
			this._lock = false;
			this.inited = false;
			//根据配置判断是否设置参考线
			GestiConfig.auxiliary && (this.auxiliary = new AuxiliaryLine());
		}
		/**
		 * @description 设置名字
		 */
		setName(name) {
			this.name = name;
		}
		init() {
			this.relativeRect = new Rect({
				x: 0,
				y: 0,
				width: this.rect.size.width,
				height: this.rect.size.height,
			});
			this.addObserver(this);
			this.inited = true;
		}
		//设置大小
		setSize(size) {
			const {
				width,
				height
			} = size;
			this.rect.setSize(width !== null && width !== void 0 ? width : this.rect.size.width,
				height !== null && height !== void 0 ? height : this.rect.size.height);
		}
		//卸载按钮
		unInstallButton(buttons) {
			this.funcButton = this.funcButton.filter((item) => !buttons.includes(item));
		}
		//安装按钮
		installButton(button) {
			this.funcButton.push(button);
		}
		/**
		 * 重置按钮
		 */
		resetButtons(excludeNames) {
			const arr = excludeNames !== null && excludeNames !== void 0 ? excludeNames : [];
			this.funcButton.forEach((button) => {
				if (!arr.includes(button.name) && !button.disabled)
					button.reset();
			});
		}
		/**
		 * @description 锁住
		 */
		lock() {
			this._lock = true;
			this.onLock();
		}
		/**
		 * @description 解锁
		 */
		unLock() {
			this._lock = false;
			this.onUnLock();
		}
		/**
		 * @description 查看是否锁住
		 */
		get isLock() {
			return this._lock;
		}
		set setLayer(layer) {
			this.layer = layer;
		}
		get getLayer() {
			return this.layer;
		}
		mirror() {
			this.isMirror = !this.isMirror;
		}
		update(paint) {
			if (!this.inited)
				return;
			this.draw(paint);
		}
		draw(paint) {
			var _a;
			paint.beginPath();
			paint.save();
			paint.translate(this.rect.position.x, this.rect.position.y);
			paint.rotate(this.rect.getAngle);
			if (this.isMirror)
				paint.scale(-1, 1);
			this.drawImage(paint);
			if (this.isMirror)
				paint.scale(-1, 1);
			if (this.selected) {
				//边框
				this.drawSelected(paint);
				//按钮
				this.updateFuncButton(paint);
			} else {
				//根据配置开关虚线框
				if (GestiConfig.dashedLine)
					this.strokeDashBorder(paint);
			}
			paint.restore();
			paint.translate(0, 0);
			/*更新顶点数据*/
			this.rect.updateVertex();
			paint.closePath();
			if (this.selected) {
				//辅助线
				(_a = this.auxiliary) === null || _a === void 0 ? void 0 : _a.draw(paint, this);
			}
		}
		//当被锁定时触发
		onLock() {
			//锁定时，自由的按钮不会消失,反之会显示
			this.funcButton.forEach((button) => {
				button.disabled = !button.isFree;
			});
		}
		//解锁时触发
		onUnLock() {
			//解锁时，自由的按钮消失,反之会显示
			this.funcButton.forEach((button) => {
				button.disabled = button.isFree;
			});
		}
		/**
		 * 被选中后外边框
		 * @param paint
		 */
		drawSelected(paint) {
			paint.beginPath();
			paint.lineWidth = 2;
			paint.strokeStyle = "#fff";
			paint.strokeRect(-this.rect.size.width >> 1, -this.rect.size.height >> 1, this.rect.size
				.width + 1, this.rect.size.height + 1);
			paint.closePath();
			paint.stroke();
		}
		/**
		 * 对象渲染虚线框
		 */
		strokeDashBorder(paint) {
			paint.closePath();
			paint.beginPath();
			paint.lineWidth = 1;
			paint.setlineDash([3, 3]);
			paint.strokeStyle = "#999";
			paint.strokeRect(-this.rect.size.width >> 1, -this.rect.size.height >> 1, this.rect.size
				.width + 1, this.rect.size.height + 1);
			paint.closePath();
			paint.stroke();
			paint.setlineDash([]);
		}
		/**
		 * 镜像翻转
		 */
		setMirror(isMirror) {
			this.isMirror = isMirror;
		}
		/**
		 * @description 刷新功能点
		 * @param paint
		 */
		updateFuncButton(paint) {
			const rect = this.rect;
			const x = rect.position.x,
				y = rect.position.y;
			this.funcButton.forEach((button) => {
				const len = button.originDistance;
				if (button.disabled)
					return;
				const angle = this.rect.getAngle + button.oldAngle;
				const newx = Math.cos(angle) * len + x;
				const newy = Math.sin(angle) * len + y;
				const vector = new Vector(~~newx, ~~newy);
				button.updatePosition(vector);
				button.update(paint);
			});
		}
		/**
		 * @description 功能点是否被点击
		 * @param eventPosition
		 * @returns
		 */
		checkFuncButton(eventPosition) {
			/**
			 * 遍历功能键
			 * 传入的时global位置，转换为相对位置判断是否点击到按钮
			 */
			const event = Vector.sub(eventPosition, this.rect.position);
			const button = this.funcButton.find((button) => {
				if (button.disabled)
					return false;
				const angle = button.oldAngle + this.rect.getAngle;
				const x = Math.cos(angle) * button.originDistance;
				const y = Math.sin(angle) * button.originDistance;
				const buttonPosi = new Vector(x, y);
				return button.isInArea(event, buttonPosi);
			});
			return button;
		}
		hide() {
			this.disabled = true;
			this.onHide();
			this.cancel();
		}
		getVertex() {
			var _a;
			return (_a = this.rect.vertex) === null || _a === void 0 ? void 0 : _a.getPoints();
		}
		onSelected() {
			var _a;
			//被选中过后对所有图层点进行备份，不需要每次渲染都获取一次
			(_a = this.auxiliary) === null || _a === void 0 ? void 0 : _a.createReferencePoint(this.key
				.toString());
			this.selected = true;
		}
		cancel() {
			this.selected = false;
		}
		onUp(paint) {
			/*在抬起鼠标时，ViewObject还没有被Calcel，为再次聚焦万向按钮做刷新数据*/
			this.onChanged();
		}
		enlarge() {
			this.scale = 1;
			this.scale += 0.1;
			this.rect.setScale(this.scale);
			this.doScale();
		}
		narrow() {
			this.scale = 1;
			this.scale -= 0.1;
			this.rect.setScale(this.scale);
			this.doScale();
		}
		doScale() {
			if (this.isLock)
				return;
			this.onChanged();
		}
		/*每次改变大小后都需要刷新按钮的数据*/
		onChanged() {
			this.funcButton.forEach((item) => {
				item.setMaster(this);
			});
		}
		/**
		 * 世界坐标居中
		 */
		center(canvasSize, axis) {
			if (axis) {
				if (axis == "vertical")
					return (this.rect.position = new Vector(this.rect.position.x, canvasSize.height >>
						1));
				if (axis == "horizon")
					return (this.rect.position = new Vector(canvasSize.width >> 1, this.rect.position
						.y));
			}
			const x = canvasSize.width >> 1,
				y = canvasSize.height >> 1;
			this.rect.position = new Vector(x, y);
		}
		/**
		 * 撤销 | 取消撤销回调
		 */
		didFallback() {}
		/**
		 * @description 提供公用基础信息导出
		 * @returns
		 */
		getBaseInfo() {
			return {
				rect: {
					x: ~~this.rect.position.x,
					y: ~~this.rect.position.y,
					width: ~~this.rect.size.width,
					height: ~~this.rect.size.height,
					angle: this.rect.getAngle,
				},
				relativeRect: {
					x: ~~this.relativeRect.position.x,
					y: ~~this.relativeRect.position.y,
					width: ~~this.relativeRect.size.width,
					height: ~~this.relativeRect.size.height,
					angle: this.rect.getAngle,
				},
				mirror: this.isMirror,
				locked: this.isLock,
				buttons: this.funcButton.map((button) => button.constructor.name),
			};
		}
		/**
		 * 自定义一些操作
		 */
		custom() {}
	}

	class ImageBox extends ViewObject {
		get value() {
			return this.image;
		}
		constructor(ximage) {
			super();
			this.family = exports.ViewObjectFamily.image;
			this.originFamily = exports.ViewObjectFamily.image;
			this.ximage = ximage;
			this.image = ximage.data;
			this.rect = new Rect(ximage.toJson());
			this.init();
		}
		setDecoration(xImage) {
			this.ximage = xImage;
			this.image = xImage.data;
			const {
				width,
				height
			} = xImage.toJson();
			const oldPosition = this.rect.position.copy();
			this.rect.setPosition(oldPosition);
			this.rect.setSize(width, height);
			this.init();
		}
		//@Override
		drawImage(paint) {
			if (this.ximage.isImageData) {
				paint.putImageData(this.image, this.rect.position.x >> 0, this.rect.position.y >> 0, 0, 0,
					this.rect.size
					.width >> 0, this.rect.size.height >> 0);
			} else
				paint.drawImage(this.image, this.rect.position.x >> 0, this.rect.position.y >> 0, this.rect
					.size
					.width >> 0, this.rect.size.height >> 0);

		}
		export (painter) {
			return __awaiter(this, void 0, void 0, function*() {
				const cutter = new Cutter(false, painter);
				const chunkSize = 500;
				const chunks = yield cutter.getChunks(chunkSize, this.ximage);
				const coverter = new ImageChunkConverter();
				const base64s = coverter.coverAllImageChunkToBase64(chunks);
				const json = {
					viewObjType: "image",
					options: Object.assign(Object.assign({
						options: {
							data: base64s,
						}
					}, this.getBaseInfo()), {
						fixedWidth: this.ximage.fixedWidth,
						fixedHeight: this.ximage.fixedHeight
					}),
				};
				return json;
			});
		}
		didDrag(value) {
			this.resetButtons(["rotate"]);
		}
		getXImage() {
			return this.ximage;
		}
	}

	/**
	 * 文字
	 */
	class TextBox extends ViewObject {
		export () {
			return __awaiter(this, void 0, void 0, function*() {
				const json = {
					viewObjType: "text",
					options: Object.assign({
						text: this._text,
						options: {
							fontSize: this.fontsize,
							color: this._color,
							spacing: this._spacing,
							fontFamily: this._fontFamily,
							// linesMarks: this.linesMarks,
							line: this._line,
							lineWidth: this.lineWidth,
							lineColor: this.lineColor,
							lineOffsetY: this.lineOffsetY,
							lineHeight: this.lineHeight,
							width: this.width,
							height: this.height,
						}
					}, this.getBaseInfo()),
				};
				return json;
			});
		}
		constructor(text, options) {
			super();
			this.family = exports.ViewObjectFamily.text;
			this.originFamily = exports.ViewObjectFamily.text;
			this._text = "";
			this.fontsize = 36;
			this._fontFamily = "微软雅黑";
			this._spacing = 0;
			this._spacing_scale = 0;
			this._line = false;
			this._color = "black";
			//划线从 奇数画到偶数，所以一般成对出现
			this.linesMarks = [];
			//下划线宽度
			this.lineWidth = 1;
			//文字间距高度
			this.lineHeight = 0;
			//下划线在Y轴上的偏移量
			this.lineOffsetY = 0;
			this.lineColor = "black";
			this.lineOneHotMark = [];
			//行？
			this.column = 0;
			//初始化默认传入高度
			this.height = 0;
			this.width = 0;
			//划线状态，1是从起点开始中 2是已经画完上一个线段了，等待下一次
			this.currentLineState = 0;
			//随着选框的变化而改变字体大小
			this.resetFontSizeWithRect = false;
			//字体大小最大值
			this.maxFontSize = 9999;
			this._painter = canvasConfig.globalPaint;
			this._options = options;
			this.initPrototypes(text, options);
			this.initColumns();
			//自定义操作
			this.custom();
		}
		//@Override
		custom() {
			//默认生成在画布中心
			this.center(canvasConfig.rect.size);
		}
		//重写被选中后的样式
		drawSelected(paint) {
			const width = this.rect.size.width,
				height = this.rect.size.height;
			paint.fillStyle = GestiConfig.theme.textSelectedMaskBgColor;
			paint.fillRect(-width >> 1, -height >> 1, width, height);
			paint.fill();
		}
		initPrototypes(text, options) {
			return __awaiter(this, void 0, void 0, function*() {
				this._text = text;
				const {
					fontFamily = this._fontFamily, fontSize = this.fontsize, spacing = this
						._spacing, color = this._color, lineWidth = this.lineWidth, lineColor =
						this.lineColor, lineOffsetY = this.lineOffsetY, lineHeight = this
						.lineHeight, line = this._line, height, width, maxFontSize,
						resetFontSizeWithRect,
				} = options !== null && options !== void 0 ? options : {};
				this._fontFamily = fontFamily;
				this.fontsize = fontSize;
				this._spacing = spacing;
				this._color = color;
				this._line = line;
				this.lineWidth = lineWidth;
				this.lineColor = lineColor;
				this.lineOffsetY = lineOffsetY;
				this.lineHeight = lineHeight;
				this.width = width;
				this.height = height;
				this.resetFontSizeWithRect = resetFontSizeWithRect;
				this.maxFontSize = maxFontSize !== null && maxFontSize !== void 0 ?
					maxFontSize : this.maxFontSize;
				//限制字体大小
				this.fontsize = Math.min(this.maxFontSize === 9999 ? fontSize : this
					.maxFontSize, fontSize);
				//计算出行距与字体大小的比例
				this._spacing_scale = this.fontsize / this._spacing;
				this._painter.font = this.fontsize + "px " + this._fontFamily;
				if (this.rect == null)
					this.rect = new Rect({
						width: width !== null && width !== void 0 ? width : this
							.getWidthSize(),
						height: height !== null && height !== void 0 ? height : this
							.fontsize,
						x: 0,
						y: 0,
					});
				this.init();
			});
		}
		/**
		 * 获取文本长度
		 */
		getWidthSize() {
			const metrics = this._painter.measureText(this._text);
			if (!metrics)
				return (this.fontsize * this._text.length + this._spacing * this._text.length);
			return metrics.width + this._spacing * this._text.length;
		}
		//@Override
		drawImage(paint) {
			/**
			 * 只用这个宽就行了，因为初始化时已经做好宽度处理，放大缩小是等比例方法缩小。
			 */
			const width = this.rect.size.width;
			//渲染文本的高度，起始点
			const height = (this.fontsize >> 1) + (this.lineHeight >> 1);
			const textList = this._text.split("");
			textList.length;
			//现在的宽度，渲染在currentWidth列
			let currentWidth = 0;
			this.column = 0;
			let oldColumn = this.column;
			paint.closePath();
			paint.beginPath();
			paint.textBaseLine = "bottom";
			paint.fillStyle = this._color;
			//设置字体大小与风格
			paint.font = this.fontsize + "px " + this._fontFamily;
			const text_len = textList.length;
			for (let ndx = 0; ndx < text_len; ndx++) {
				const text = textList[ndx];
				const measureText = this._painter.measureText(text);
				const text_width = ~~measureText.width;
				const beforeText = this._text[ndx - 1];
				const nextText = this._text[ndx + 1];
				const spacing = this.fontsize / this._spacing_scale;
				const x = text_width + spacing;
				const rep = / &n/g;
				const isAutoColumn = rep.test(beforeText + text + nextText);
				/**
				 * 宽度不足一个字体，接下来要换行才行，还未换行
				 */
				if (width - currentWidth - x < text_width ||
					(isAutoColumn && this.column == oldColumn)) {
					//上一个为1,且马上要被替换的必须为0
					if (this.currentLineState == 1 &&
						this.lineOneHotMark[ndx] == 0 &&
						this.lineOneHotMark[ndx - 1] != 4)
						this.lineOneHotMark[ndx] = 4;
				}
				//字数达到宽度后需要换行   或者出发换行字符
				if (currentWidth + x > width || isAutoColumn) {
					this.column += 1;
					currentWidth = 0;
				}
				const drawX = width * -0.5 + currentWidth;
				const drawY = (this.column == 0 ? height * 0 : height * (this.column * 2)) -
					(this.rect.size.height >> 1);
				if (!isAutoColumn) {
					const offsetY = height + (this.fontsize >> 1) - this.fontsize * 0.1;
					const offsetX = (x - text_width) >> 1;
					if (this._line) {
						paint.moveTo(drawX, drawY + offsetY + this.lineOffsetY);
						paint.lineTo(drawX + (text_width + this._spacing), drawY + offsetY + this
							.lineOffsetY);
					}
					paint.fillText(text, drawX + offsetX, drawY + offsetY);
					currentWidth += x;
				}
				if (isAutoColumn) {
					ndx += 1;
					paint.stroke();
					continue;
				}
			}
			paint.strokeStyle = this.lineColor;
			paint.lineWidth = this.lineWidth;
			paint.stroke();
			paint.closePath();
			this.setData();
		}
		initColumns() {
			/**
			 * 只用这个宽就行了，因为初始化时已经做好宽度处理，放大缩小是等比例方法缩小。
			 */
			const width = this.rect.size.width;
			//渲染文本的高度，起始点
			(this.fontsize >> 1) + (this.lineHeight >> 1);
			const textList = this._text.split("");
			textList.length;
			//现在的宽度，渲染在currentWidth列
			let currentWidth = 0;
			this.column = 0;
			//设置字体大小与风格
			this._painter.font = this.fontsize + "px " + this._fontFamily;
			const text_len = textList.length;
			for (let ndx = 0; ndx < text_len; ndx++) {
				const text = textList[ndx];
				const measureText = this._painter.measureText(text);
				const text_width = ~~measureText.width;
				const beforeText = this._text[ndx - 1];
				const nextText = this._text[ndx + 1];
				const spacing = this.fontsize / this._spacing_scale;
				const x = text_width + spacing;
				const rep = / &n/g;
				const isAutoColumn = rep.test(beforeText + text + nextText);
				//字数达到宽度后需要换行   或者出发换行字符
				if (currentWidth + x > width || isAutoColumn) {
					this.column += 1;
					currentWidth = 0;
				}
				if (!isAutoColumn) {
					currentWidth += x;
				}
				if (isAutoColumn) {
					ndx += 1;
					continue;
				}
			}
			this.setData();
			this.update(this._painter);
		}
		// - (textWidth + this._spacing)
		//@Override
		didChangeScale(scale) {
			this.setData();
			this.update(this._painter);
		}
		//更新文字内容
		updateText(text, options) {
			return new Promise((r, j) => {
				this._text = text;
				this.initPrototypes(text, options);
				this.update(this._painter);
				this.setData();
				r();
			});
		}
		setDecoration(options) {
			this.initPrototypes(this._text, options);
			this.update(this._painter);
			this.setData();
		}
		didFallback() {
			this.setData();
		}
		/**
		 * @description 宽不随文字变化，但文字随宽变化,高度随字体变化
		 */
		setData() {
			return __awaiter(this, void 0, void 0, function*() {
				//随着选框的变化改变字体大小
				if (this.resetFontSizeWithRect) {
					this.fontsize = Math.min(this.rect.size.height, this.maxFontSize);
				} else {
					const {
						size
					} = this.rect;
					let newHeight = (this.fontsize + this.lineHeight) * (this.column + 1);
					// if (newHeight < size.height) {
					//   newHeight = size.height;
					// }
					let newWidth = this.rect.size.width;
					if (newWidth >= canvasConfig.rect.size.width)
						newWidth = canvasConfig.rect.size.width;
					this.rect.setSize(newWidth, newHeight);
					this.resetButtons(["rotate"]);
					if (size.width <= this.fontsize + this._spacing)
						this.rect.setSize(this.fontsize + this._spacing, newHeight);
				}
				return Promise.resolve();
			});
		}
		get value() {
			return this._text;
		}
		get fontColor() {
			return this._color;
		}
		get fontSize() {
			return this.fontsize;
		}
	}

	/**
	 * 实现逻辑
	 * 新建一个 canvas等宽高的矩阵,锁定它，
	 *
	 */
	class WriteViewObj extends ViewObject {
		export () {
			return __awaiter(this, void 0, void 0, function*() {
				this.points.forEach((item) => {
					item.x = ~~item.x;
					item.y = ~~item.y;
				});
				const json = {
					viewObjType: "write",
					options: Object.assign({
						config: Object.assign(Object.assign({}, this.config), {
							scaleX: this._scalex,
							scaleY: this._scaley
						}),
						points: this.points
					}, this.getBaseInfo()),
				};
				return json;
			});
		}
		constructor(points, color, config) {
			var _a, _b, _c, _d, _e;
			super();
			this.family = exports.ViewObjectFamily.write;
			this.points = [];
			this._scalex = 1;
			this._scaley = 1;
			this.color = "";
			this.isFill = false;
			this.originFamily = exports.ViewObjectFamily.write;
			this.type = "write";
			this.lineWidth = 3;
			this.points = points;
			this.type = config.type;
			this.color = (_a = config.color) !== null && _a !== void 0 ? _a : "black";
			this.isFill = (_b = config.isFill) !== null && _b !== void 0 ? _b : false;
			this.lineWidth = (_c = config.lineWidth) !== null && _c !== void 0 ? _c : 3;
			this._scalex = (_d = config.scaleX) !== null && _d !== void 0 ? _d : 1;
			this._scaley = (_e = config.scaleY) !== null && _e !== void 0 ? _e : 1;
			this.config = config;
		}
		setDecoration(decoration) {
			this.color = decoration === null || decoration === void 0 ? void 0 : decoration.color;
			this.isFill = decoration === null || decoration === void 0 ? void 0 : decoration.isFill;
			this.lineWidth = decoration === null || decoration === void 0 ? void 0 : decoration
				.lineWidth;
		}
		//供外部设置数据
		setParams(config) {
			var _a, _b, _c, _d, _e;
			this.type = config.type;
			this.color = (_a = config.color) !== null && _a !== void 0 ? _a : "black";
			this.isFill = (_b = config.isFill) !== null && _b !== void 0 ? _b : false;
			this.lineWidth = (_c = config.lineWidth) !== null && _c !== void 0 ? _c : 3;
			this._scalex = (_d = config.scaleX) !== null && _d !== void 0 ? _d : 1;
			this._scaley = (_e = config.scaleY) !== null && _e !== void 0 ? _e : 1;
			this.config = config;
			this.custom();
		}
		custom() {
			//线条没有填充
			if (this.type == "line") {
				this.isFill = false;
				this.family = exports.ViewObjectFamily.line;
			} else if (this.type == "rect") {
				this.family = exports.ViewObjectFamily.rect;
			} else if (this.type == "circle") {
				this.family = exports.ViewObjectFamily.circle;
			} else if (this.type == "write") {
				this.family = exports.ViewObjectFamily.write;
			}
		}
		//重写被选中后的样式
		drawSelected(paint) {
			paint.beginPath();
			const width = this.rect.size.width,
				height = this.rect.size.height;
			paint.fillStyle = GestiConfig.theme.textSelectedMaskBgColor;
			paint.fillRect(-width >> 1, -height >> 1, width, height);
			paint.closePath();
			paint.fill();
		}
		drawImage(paint) {
			paint.closePath();
			paint.strokeStyle = this.color;
			const len = this.points.length;
			paint.beginPath();
			//普通涂鸦
			if (this.type == "write")
				for (let i = 1; i < len; i++) {
					const currentPoint = this.points[i];
					const beforePoint = this.points[i - 1];
					paint.lineCap = "round";
					let prex = beforePoint.x,
						prey = beforePoint.y;
					let curx = currentPoint.x,
						cury = currentPoint.y;
					let cx = (prex + curx) * 0.5;
					let cy = (prey + cury) * 0.5;
					paint.quadraticCurveTo(prex * this._scalex, prey * this._scaley, cx * this._scalex,
						cy * this._scaley);
				}
			if (this.type == "rect" || this.type == "line")
				for (let i = 0; i < len; i++) {
					const point = this.points[i];
					if (i == 0)
						paint.moveTo(point.x * this._scalex, point.y * this._scaley);
					paint.lineTo(point.x * this._scalex, point.y * this._scaley);
				}
			if (this.type == "circle") {
				const {
					sx,
					sy,
					x,
					y,
					minx,
					miny,
					width,
					height
				} = this.getCircleParams(this.points[0], this.points[1]);
				paint.ellipse(minx + width * 0.5, miny + height * 0.5, width * 0.5, height * 0.5);
			}
			paint.lineWidth = this.lineWidth;
			paint.strokeStyle = this.color;
			if (this.type != "write")
				paint.closePath();
			if (this.isFill) {
				paint.fillStyle = this.color;
				paint.fill();
			} else
				paint.stroke();
			if (this.type == "write")
				paint.closePath();
			paint.closePath();
		}
		getCircleParams(p1, p2) {
			const sx = p1.x * this._scalex,
				sy = p1.y * this._scaley;
			const x = p2.x * this._scalex,
				y = p2.y * this._scaley;
			const width = Math.abs(sx - x),
				height = Math.abs(sy - y);
			const minx = Math.min(x, sx),
				miny = Math.min(y, sy);
			return {
				sx,
				sy,
				x,
				y,
				minx,
				miny,
				width,
				height,
			};
		}
		didChangeScale(scale) {
			this._scalex = this.rect.size.width / this.relativeRect.size.width;
			this._scaley = this.rect.size.height / this.relativeRect.size.height;
			if (this.type == "rect");
		}
		get value() {
			return Object.assign(Object.assign({}, this.config), {
				points: this.points
			});
		}
	}

	class GestiReader {
		constructor() {
			this.buttonClazzList = {
				CloseButton,
				DragButton,
				MirrorButton,
				RotateButton,
				LockButton,
				UnLockButton,
				VerticalButton,
				HorizonButton,
			};
		}
		getObjectByJson(str, weChatCanvas) {
			var _a, _b;
			return __awaiter(this, void 0, void 0, function*() {
				const json = JSON.parse(str);
				const {
					options
				} = json;
				const rect = this.getRectByRectJson(options.rect);
				const relativeRect = this.getRectByRectJson(options.relativeRect);
				let viewObject;
				switch (json.viewObjType) {
					case "write": {
						viewObject = new WriteViewObj(options.points, (_b = (_a = options
								.config) === null || _a === void 0 ? void 0 : _a.color) !==
							null && _b !== void 0 ? _b : "red", options.config);
					}
					break;
					case "image": {
						const cutter = new Cutter();
						const covter = new ImageChunkConverter();
						// console.log("画布",weChatCanvas.createImage);
						const source = cutter.merge(options.fixedWidth, options.fixedHeight,
							options.options.data, weChatCanvas);

						const image = weChatCanvas.createImage();
						const offCanvas = wx.createOffscreenCanvas({
							type: "2d",
							width: options.fixedWidth,
							height: options.fixedHeight,
						});
						const offPaint = offCanvas.getContext("2d");
						offPaint.putImageData(source, 0, 0);
						const ximage = new XImage({
							data: offCanvas,
							width: options.rect.width,
							height: options.rect.height,
						});
						viewObject = new ImageBox(ximage);
					}
					break;
					case "text": {
						viewObject = new TextBox(options.text, options.options);
					}
					break;
				}
				if (!viewObject.rect)
					viewObject.rect = rect;
				if (!viewObject.relativeRect)
					viewObject.relativeRect = relativeRect;
				viewObject.setMirror(options.mirror);
				viewObject.rect.setSize(rect.size.width, rect.size.height);
				viewObject.rect.setAngle(options.rect.angle);
				viewObject.relativeRect.position = relativeRect.position;
				viewObject.relativeRect.setSize(relativeRect.size.width, relativeRect.size
					.height);
				viewObject.relativeRect.setAngle(options.relativeRect.getAngle);
				viewObject.init();
				//init包括生成按钮
				options.locked && viewObject.lock();
				viewObject.custom();
				viewObject.rect.setPosition(rect.position);
				this.installButton(viewObject, options.buttons);
				return viewObject;
			});
		}
		//安装按钮
		installButton(viewObject, buttons) {
			buttons.forEach((item) => {
				const button = new this.buttonClazzList[item](viewObject);
				viewObject.installButton(button);
			});
		}
		getRectByRectJson(rectJson) {
			const jsonObj = rectJson;
			const rect = new Rect({
				width: jsonObj.width,
				height: jsonObj.height,
				x: jsonObj.x,
				y: jsonObj.y,
			});
			return rect;
		}
	}

	/**
	 * 绘制类别
	 */
	class WriteBase {
		constructor(paint) {
			//是否禁止除了本类以外的对象重绘
			this.disableCanvasUpdate = false;
			this.color = "orange";
			/**
			 * 收集在绘制过程中的最大点和最小点，以便于得到最终的矩形高宽
			 */
			this.maxX = 0;
			this.maxY = 0;
			this.minX = 9999;
			this.minY = 9999;
			this.paint = paint;
		}
		reset() {
			this.maxX = 0;
			this.maxY = 0;
			this.minX = 9999;
			this.minY = 9999;
		}
		onDown(position) {
			if (!Array.isArray(position)) {
				this.draw(position);
			}
		}
		onUp(position) {
			if (!Array.isArray(position))
				this.draw(position);
		}
		onMove(position) {
			if (!Array.isArray(position)) {
				if (!this.startPoint)
					this.startPoint = position;
				//this.paint.clearRect(0,0,9999,9999);
				this.draw(position);
				const [x, y] = position.toArray();
				this.maxX = Math.max(x, this.maxX);
				this.maxY = Math.max(y, this.maxY);
				this.minY = Math.min(y, this.minY);
				this.minX = Math.min(x, this.minX);
			}
		}
		getRect() {
			const width = this.maxX - this.minX;
			const height = this.maxY - this.minY;
			const rect = new Rect({
				width,
				height,
				x: this.minX + width / 2,
				y: this.minY + height / 2
			});
			return rect;
		}
		setConfig(config) {
			this.config = config;
			//设置默认数值
			if (!this.config.lineWidth)
				this.config.lineWidth = 3;
			if (!this.config.color)
				this.config.color = "red";
			if (!this.config.isFill)
				this.config.isFill = false;
		}
	}

	class WriteCircle extends WriteBase {
		constructor() {
			super(...arguments);
			this.currentPosition = new Vector(0, 0);
			this.points = [];
		}
		draw(position) {
			var _a;
			this.currentPosition = position;
			const {
				sx,
				sy,
				x,
				y,
				minx,
				miny,
				width,
				height
			} = this.getParams();
			this.paint.lineWidth = this.config.lineWidth;
			this.paint.strokeStyle = this.config.color;
			this.paint.ellipse(minx + width * 0.5, miny + height * 0.5, width * 0.5, height * 0.5);
			if ((_a = this.config.isFill) !== null && _a !== void 0 ? _a : false) {
				this.paint.fillStyle = this.config.color;
				this.paint.fill();
			} else
				this.paint.stroke();
			this.paint.fillRect(sx, sy, 3, 3);
			this.paint.fillRect(x, sy, 3, 3);
			this.paint.fillRect(x, y, 3, 3);
			this.paint.fillRect(sx, y, 3, 3);
		}
		getParams() {
			const sx = this.startPoint.x,
				sy = this.startPoint.y;
			const x = this.currentPosition.x,
				y = this.currentPosition.y;
			const width = Math.abs(sx - x),
				height = Math.abs(sy - y);
			const minx = Math.min(x, sx),
				miny = Math.min(y, sy);
			return {
				sx,
				sy,
				x,
				y,
				minx,
				miny,
				width,
				height,
			};
		}
		getWriteViewObject() {
			return __awaiter(this, void 0, void 0, function*() {
				if (!this.startPoint)
					return null;
				const {
					sx,
					sy,
					x,
					y,
					minx,
					miny,
					width,
					height
				} = this.getParams();
				const p1 = new Vector(sx, sy),
					p2 = new Vector(x, y);
				this.points = [p1, p2];
				const rect = new Rect({
					width,
					height,
					x: minx + width * 0.5,
					y: miny + height * 0.5,
				});
				const rx = rect.position.x,
					ry = rect.position.y;
				this.points.forEach((item) => {
					item.x -= rx;
					item.y -= ry;
				});
				const viewobj = new WriteViewObj(this.points, this.color, this.config);
				viewobj.rect = rect;
				viewobj.init();
				this.reset();
				this.points = [];
				return viewobj;
			});
		}
	}

	class WriteLine extends WriteBase {
		constructor() {
			super(...arguments);
			this.currentPosition = new Vector(0, 0);
			this.points = [];
		}
		draw(position) {
			const sx = this.startPoint.x,
				sy = this.startPoint.y;
			const x = position.x,
				y = position.y;
			this.paint.beginPath();
			this.paint.moveTo(sx, sy);
			this.paint.lineTo(x, y);
			this.paint.lineJoin = "round";
			this.paint.lineCap = "round";
			this.paint.lineWidth = this.config.lineWidth;
			this.paint.strokeStyle = this.config.color;
			this.paint.stroke();
			this.paint.closePath();
			this.currentPosition = position;
		}
		getWriteViewObject() {
			return __awaiter(this, void 0, void 0, function*() {
				if (!this.startPoint)
					return null;
				const sx = this.startPoint.x,
					sy = this.startPoint.y;
				const x = this.currentPosition.x,
					y = this.currentPosition.y;
				const minx = Math.min(x, sx),
					miny = Math.min(y, sy);
				const sub = Vector.sub(this.currentPosition, this.startPoint);
				const dt = Vector.dist(this.currentPosition, this.startPoint);
				const angle = Math.atan2(sub.y, sub.x);
				const cy = miny + Math.abs(sy - y) * .5;
				//已知直径，中心点，
				const rect = new Rect({
					width: dt,
					height: 30,
					x: minx + Math.abs(sx - x) * .5,
					y: miny + Math.abs(sy - y) * .5,
				});
				rect.setAngle(angle);
				this.points = [
					new Vector(rect.position.x - dt * .5, cy),
					new Vector(rect.position.x + dt * .5, cy),
				];
				const rx = rect.position.x,
					ry = rect.position.y;
				this.points.forEach((item) => {
					item.x -= rx;
					item.y -= ry;
				});
				const viewobj = new WriteViewObj(this.points, this.color, this.config);
				viewobj.rect = rect;
				viewobj.init();
				// viewobj.dragButton.setAxis("horizontal");
				this.reset();
				this.points = [];
				return viewobj;
			});
		}
	}

	class WriteRect extends WriteBase {
		constructor() {
			super(...arguments);
			this.points = [];
			this.currentPosition = new Vector(0, 0);
		}
		draw(position) {
			var _a;
			this.paint.beginPath();
			const sx = this.startPoint.x,
				sy = this.startPoint.y;
			const x = position.x,
				y = position.y;
			this.paint.lineJoin = "round";
			this.paint.lineCap = "round";
			this.paint.moveTo(sx, sy);
			this.paint.lineTo(x, sy);
			this.paint.lineTo(x, y);
			this.paint.lineTo(sx, y);
			this.paint.closePath();
			this.paint.strokeStyle = this.config.color;
			this.paint.lineWidth = this.config.lineWidth;
			if ((_a = this.config.isFill) !== null && _a !== void 0 ? _a : false) {
				this.paint.fillStyle = this.config.color;
				this.paint.fill();
			} else
				this.paint.stroke();
			this.currentPosition = position;
		}
		getWriteViewObject() {
			return __awaiter(this, void 0, void 0, function*() {
				if (!this.startPoint)
					return null;
				const sx = this.startPoint.x,
					sy = this.startPoint.y;
				const x = this.currentPosition.x,
					y = this.currentPosition.y;
				const width = Math.abs(sx - x),
					height = Math.abs(sy - y);
				const minx = Math.min(x, sx),
					miny = Math.min(y, sy);
				const rect = new Rect({
					width,
					height,
					x: minx + width * .5,
					y: miny + height * .5,
				});
				const p1 = new Vector(sx, sy),
					p2 = new Vector(x, sy),
					p3 = new Vector(x, y),
					p4 = new Vector(sx, y);
				this.points = [p1, p2, p3, p4];
				const rx = rect.position.x,
					ry = rect.position.y;
				this.points.forEach((item) => {
					item.x -= rx;
					item.y -= ry;
				});
				const viewobj = new WriteViewObj(this.points, this.color, this.config);
				viewobj.rect = rect;
				viewobj.init();
				this.reset();
				this.points = [];
				return viewobj;
			});
		}
	}

	/**
	 * 写的时候的类，并不是ViewObject图册
	 * https://www.cnblogs.com/fangsmile/p/14324460.html
	 *
	 * donw在某个被选中的物体之中时，不能开始绘制
	 */
	class Write extends WriteBase {
		constructor() {
			super(...arguments);
			this.points = [];
			//速度越快，线越细
			// private lineWidth(v1: Vector, v2: Vector): number {
			//     const maxWidth:number=10;
			//     const minWidth:number=3;
			//     const dt: number = Vector.dist(v1, v2);
			//     const speed=dt/maxWidth;
			//     const width = (maxWidth-minWidth)*speed+minWidth;
			//     return width;
			// }
		}
		getWriteViewObject() {
			return __awaiter(this, void 0, void 0, function*() {
				const rect = this.getRect();
				const x = rect.position.x,
					y = rect.position.y;
				this.points.forEach((item) => {
					item.x -= x;
					item.y -= y;
				});
				if (this.points.length < 2)
					return null;
				const viewobj = new WriteViewObj(this.points, this.color, this.config);
				viewobj.rect = rect;
				viewobj.init();
				this.reset();
				this.points = [];
				return viewobj;
			});
		}
		draw(position) {
			this.paint.strokeStyle = this.color;
			this.points.push(position);
			if (this.points.length < 1)
				return;
			const len = this.points.length;
			this.paint.beginPath();
			for (let i = 1; i < len; i++) {
				const currentPoint = this.points[i];
				const beforePoint = this.points[i - 1];
				this.paint.lineCap = "round";
				let prex = beforePoint.x,
					prey = beforePoint.y;
				let curx = currentPoint.x,
					cury = currentPoint.y;
				let cx = (prex + curx) * .5;
				let cy = (prey + cury) * .5;
				// this.paint.beginPath();
				// this.paint.moveTo(prex,prey);
				// this.paint.lineTo(curx,cury);
				this.paint.quadraticCurveTo(prex, prey, cx, cy);
				this.paint.lineWidth = 3; //this.lineWidth(this.lastPosition, position);
			}
			this.paint.strokeStyle = this.config.color;
			this.paint.lineWidth = this.config.lineWidth;
			this.paint.stroke();
			this.paint.closePath();
		}
	}

	var WriteType;
	(function(WriteType) {
		WriteType[WriteType["None"] = 0] = "None";
		WriteType[WriteType["Write"] = 1] = "Write";
		WriteType[WriteType["Rect"] = 2] = "Rect";
		WriteType[WriteType["Circle"] = 3] = "Circle";
		WriteType[WriteType["Line"] = 4] = "Line";
	})(WriteType || (WriteType = {}));
	/**
	 * down在已被选中图册上时不能绘制，
	 * 当down图册上时  current=null,
	 * 需要存储被选中绘制的类型
	 * 每个类的生命周期为   down-move-up-诞生图册-长存
	 * down需要做动作:判定是否在选定图册内,没有就new对象
	 *
	 */
	class WriteFactory {
		setConfig(config) {
			this.config = config;
			this.setWriteType();
		}
		constructor(paint) {
			//当前画笔类型
			this.currentType = WriteType.None;
			this.paint = paint;
		}
		setWriteType() {
			if (this.config.type == "none")
				this.currentType = WriteType.None;
			if (this.config.type == "circle")
				this.currentType = WriteType.Circle;
			if (this.config.type == "write")
				this.currentType = WriteType.Write;
			if (this.config.type == "line")
				this.currentType = WriteType.Line;
			if (this.config.type == "rect")
				this.currentType = WriteType.Rect;
		}
		onDraw() {
			var _a;
			switch (this.currentType) {
				case WriteType.Write:
					this.current = this.write();
					break;
				case WriteType.Rect:
					this.current = this.rect();
					break;
				case WriteType.Line:
					this.current = this.line();
					break;
				case WriteType.Circle:
					this.current = this.circle();
					break;
			}
			/**
			 * 设置配置
			 */
			(_a = this.current) === null || _a === void 0 ? void 0 : _a.setConfig(this.config);
		}
		/**
		 *
		 * @returns 普通的绘制类
		 */
		write() {
			const write = new Write(this.paint);
			write.disableCanvasUpdate = true;
			this.current = write;
			return write;
		}
		/**
		 *
		 * @returns 矩形绘制类
		 */
		rect() {
			const writeRect = new WriteRect(this.paint);
			writeRect.disableCanvasUpdate = true;
			this.current = writeRect;
			return writeRect;
		}
		/**
		 *
		 * @returns 线绘制类
		 */
		line() {
			const writeline = new WriteLine(this.paint);
			writeline.disableCanvasUpdate = true;
			this.current = writeline;
			return writeline;
		}
		/**
		 *
		 * @returns 圆圈绘制类
		 */
		circle() {
			const writecircle = new WriteCircle(this.paint);
			writecircle.disableCanvasUpdate = true;
			this.current = writecircle;
			return writecircle;
		}
		//绘制完毕，返回一个可操作对象
		done() {
			return __awaiter(this, void 0, void 0, function*() {
				if (!this.current)
					return Promise.resolve(null);
				const obj = yield this.current.getWriteViewObject();
				obj === null || obj === void 0 ? void 0 : obj.custom();
				if (obj === null || obj === void 0 ? void 0 : obj.rect) {
					//太小的不要
					const {
						width,
						height
					} = obj.rect.size;
					if (width <= 3 && height <= 3)
						return Promise.resolve(null);
				}
				this.current = null;
				return obj;
			});
		}
		cancel() {
			this.current = null;
		}
	}

	var EventHandlerState;
	(function(EventHandlerState) {
		EventHandlerState[EventHandlerState["down"] = 0] = "down";
		EventHandlerState[EventHandlerState["up"] = 1] = "up";
		EventHandlerState[EventHandlerState["move"] = 2] = "move";
	})(EventHandlerState || (EventHandlerState = {}));
	/**
	 * 图层操作枚举
	 */
	var LayerOperationType;
	(function(LayerOperationType) {
		//下降一层
		LayerOperationType[LayerOperationType["lower"] = 0] = "lower";
		//上升一层
		LayerOperationType[LayerOperationType["rise"] = 1] = "rise";
		//至于顶层
		LayerOperationType[LayerOperationType["top"] = 2] = "top";
		//至于底层
		LayerOperationType[LayerOperationType["bottom"] = 3] = "bottom";
	})(LayerOperationType || (LayerOperationType = {}));
	/**
	 * 监听类
	 */
	class Listeners {
		constructor() {
			this.hooks = {};
		}
		addHook(hookType, hook, prepend = false) {
			const hooks = this.hooks[hookType] || (this.hooks[hookType] = []);
			const wrappedHook = hook.__weh || (hook.__weh = (arg) => hook(arg));
			//优先级
			if (prepend) {
				hooks.unshift(wrappedHook);
			} else {
				hooks.push(wrappedHook);
			}
			return wrappedHook;
		}
		callHooks(hookType, arg) {
			const hooks = this.hooks[hookType] || [];
			hooks.forEach((hook) => hook(arg));
		}
		removeHook(hookType, hook) {
			const hooks = this.hooks[hookType] || [];
			const ndx = hooks.indexOf(hook);
			hooks.splice(ndx, 1);
		}
	}
	class ImageToolkit {
		get getCanvasRect() {
			return this.canvasRect;
		}
		get getViewObjects() {
			return this.ViewObjectList;
		}
		constructor(paint, rect) {
			//所有图层集合
			this.ViewObjectList = new Array();
			//手势状态
			this.eventHandlerState = EventHandlerState.up;
			//拖拽代理器
			this.drag = new Drag();
			//手势处理识别器
			this.gesture = new Gesture();
			//当前选中的图层
			this.selectedViewObject = null;
			//是否debug模式
			this.isDebug = false;
			//记录操作
			this.recorder = Recorder.getInstance();
			/**
			 * 本次点击是否有选中到对象，谈起时需要置于false
			 */
			this._inObjectArea = false;
			/**
			 * 工具
			 */
			this.tool = new _Tools();
			this.listen = new Listeners();
			/**
			 * 目前图层的显示状态，0表示隐藏，1表示显示
			 */
			this.currentViewObjectState = [];
			//是否在绘制中
			this.isWriting = false;
			//目前Hover的对象
			this.hoverViewObject = null;
			//测试 将canvas快照下来，除了被选中的对象，其他都按按照这个渲染
			this.snapshot = null;
			//休眠,休眠时不能有任何操作
			this.sleep = false;
			const {
				x: offsetx,
				y: offsety,
				width,
				height
			} = rect;
			this.offset = new Vector(offsetx || 0, offsety || 0);
			rect.x = this.offset.x;
			rect.y = this.offset.y;
			this.canvasRect = new Rect(rect);
			this.paint = new Painter(paint);
			canvasConfig.setGlobalPaint(this.paint);
			this.writeFactory = new WriteFactory(this.paint);
			this.bindEvent();
		}
		destroyGesti() {
			this.callHook("onBeforeDestroy");
			this.ViewObjectList = [];
			this.eventHandler = null;
			this.tool = null;
			new Promise((v, r) => {
				this.callHook("onDestroy");
			}).then((e) => {
				this.listen = null;
			});
			//监听器最后销毁，因为要执行回调
		}
		load(view) {
			this.addViewObject(view);
		}
		select(select) {
			if (select && select.onSelected) {
				select.onSelected();
				this.selectedViewObject = select;
				this.callHook("onSelect", select);
				this.update();
				return Promise.resolve();
			}
			return Promise.resolve();
		}
		get currentViewObject() {
			return this.selectedViewObject;
		}
		rotate(angle, existing, view) {
			return __awaiter(this, void 0, void 0, function*() {
				let obj = view || this.selectedViewObject;
				if (!obj)
					return Promise.resolve(null);
				let _angle = existing ? angle + obj.rect.getAngle : angle;
				obj.rect.setAngle(_angle);
				this.update();
				return Promise.resolve(null);
			});
		}
		upward(viewObject) {
			if (viewObject) {
				viewObject.rect.position.y -= 1;
				return viewObject.rect.position.y;
			}
			if (!this.selectedViewObject)
				return null;
			this.selectedViewObject.rect.position.y -= 1;
			return this.selectedViewObject.rect.position.y;
		}
		downward(viewObject) {
			if (viewObject) {
				viewObject.rect.position.y += 1;
				return viewObject.rect.position.y;
			}
			if (!this.selectedViewObject)
				return null;
			this.selectedViewObject.rect.position.y += 1;
			return this.selectedViewObject.rect.position.y;
		}
		leftward(viewObject) {
			if (viewObject) {
				viewObject.rect.position.x -= 1;
				return viewObject.rect.position.x;
			}
			if (!this.selectedViewObject)
				return null;
			this.selectedViewObject.rect.position.x -= 1;
			return this.selectedViewObject.rect.position.x;
		}
		rightward(viewObject) {
			if (viewObject) {
				viewObject.rect.position.x += 1;
				return viewObject.rect.position.x;
			}
			if (!this.selectedViewObject)
				return null;
			this.selectedViewObject.rect.position.x += 1;
			return this.selectedViewObject.rect.position.x;
		}
		/**
		 * @description 导入json解析成对象
		 * @param json
		 * @returns
		 */
		importAll(json, weChatCanvas) {
			return __awaiter(this, void 0, void 0, function*() {
				return new Promise((r, j) => __awaiter(this, void 0, void 0, function*() {
					var _a, e_1, _b, _c;
					try {
						if (json == "[]" || !json)
							throw Error("Import Json is Empty");
						const str = JSON.parse(json);
						const reader = new GestiReader();
						try {
							for (var _d = true, str_1 = __asyncValues(str),
									str_1_1; str_1_1 = yield str_1.next(), _a =
									str_1_1
									.done, !_a;) {
								_c = str_1_1.value;
								_d = false;
								try {
									const item = _c;
									const obj = yield reader.getObjectByJson(JSON
										.stringify(item), weChatCanvas);

									console.log("得到", obj.image);
									if (obj)
										this.addViewObject(obj);
								} finally {
									_d = true;
								}
							}
						} catch (e_1_1) {
							e_1 = {
								error: e_1_1
							};
						} finally {
							try {
								if (!_d && !_a && (_b = str_1.return)) yield _b
									.call(str_1);
							} finally {
								if (e_1) throw e_1.error;
							}
						}
						this.update();
						r();
					} catch (error) {
						j(error);
					}
				}));
			});
		}
		addListener(listenType, hook, prepend = false) {
			return this.listen.addHook(listenType, hook, prepend);
		}
		removeListener(listenType, hook) {
			this.listen.removeHook(listenType, hook);
		}
		/**
		 * @description 导出画布内所有对象成json字符串
		 */
		exportAll(offScreenPainter) {
			const offPainter = new Painter(offScreenPainter);
			return new Promise((r, j) => __awaiter(this, void 0, void 0, function*() {
				var _a, e_2, _b, _c;

				try {
					const jsons = [];
					try {
						for (var _d = true, _e = __asyncValues(this.ViewObjectList),
								_f; _f = yield _e.next(), _a = _f.done, !_a;) {
							_c = _f.value;
							_d = false;
							try {
								const item = _c;
								if (item.disabled)
									continue;
								jsons.push(yield item.export(offPainter));
							} finally {
								_d = true;
							}
						}
					} catch (e_2_1) {
						e_2 = {
							error: e_2_1
						};
					} finally {
						try {
							if (!_d && !_a && (_b = _e.return)) yield _b.call(_e);
						} finally {
							if (e_2) throw e_2.error;
						}
					}
					r(JSON.stringify(jsons));
				} catch (error) {
					j(error);
				}
			}));
		}
		updateText(text, options) {
			const isTextBox = classTypeIs(this.selectedViewObject, TextBox);
			if (isTextBox) {
				this.selectedViewObject
					.updateText(text, options)
					.then(() => {
						this.update();
					});
			}
		}
		center(axis, view) {
			var _a;
			if (view)
				view.center(this.canvasRect.size, axis);
			else
				(_a = this.selectedViewObject) === null || _a === void 0 ? void 0 : _a.center(this
					.canvasRect.size, axis);
		}
		cancel(view) {
			const _view = view || this.selectedViewObject;
			if (_view) {
				if (_view.key == this.selectedViewObject.key)
					this.selectedViewObject = null;
				_view === null || _view === void 0 ? void 0 : _view.cancel();
				this.callHook("onCancel", _view);
			}
			this.update();
		}
		cancelAll() {
			this.ViewObjectList.forEach((item) => item.cancel());
			this.update();
		}
		layerLower(view) {
			let _view = view || this.selectedViewObject;
			this.tool.arrangeLayer(this.ViewObjectList, _view, LayerOperationType.lower);
		}
		layerRise(view) {
			let _view = view || this.selectedViewObject;
			this.tool.arrangeLayer(this.ViewObjectList, _view, LayerOperationType.rise);
		}
		layerTop(view) {
			let _view = view || this.selectedViewObject;
			this.tool.arrangeLayer(this.ViewObjectList, _view, LayerOperationType.top);
		}
		layerBottom(view) {
			let _view = view || this.selectedViewObject;
			this.tool.arrangeLayer(this.ViewObjectList, _view, LayerOperationType.bottom);
		}
		unLock(view) {
			var _a;
			if (view)
				view === null || view === void 0 ? void 0 : view.unLock();
			else
				(_a = this.selectedViewObject) === null || _a === void 0 ? void 0 : _a.unLock();
		}
		lock(view) {
			var _a;
			if (view)
				view === null || view === void 0 ? void 0 : view.lock();
			else
				(_a = this.selectedViewObject) === null || _a === void 0 ? void 0 : _a.lock();
		}
		fallback() {
			return __awaiter(this, void 0, void 0, function*() {
				const node = yield this.recorder.fallback();
				this.tool.fallbackViewObject(this.ViewObjectList, node, this);
			});
		}
		cancelFallback() {
			return __awaiter(this, void 0, void 0, function*() {
				const node = yield this.recorder.cancelFallback();
				this.tool.fallbackViewObject(this.ViewObjectList, node, this);
			});
		}
		//无须实现
		down(e) {
			throw new Error("Method not implemented.");
		}
		//无须实现
		up(e) {
			throw new Error("Method not implemented.");
		}
		//无须实现
		move(e) {
			throw new Error("Method not implemented.");
		}
		//无须实现
		wheel(e) {
			throw new Error("Method not implemented.");
		}
		//无需实现
		createImage(image, options) {
			throw new Error("Method not implemented.");
		}
		bindEvent() {
			this.eventHandler = new GestiEventManager().getEvent(this);
			if (this.eventHandler == null)
				return;
			this.eventHandler
				.down(this.onDown)
				.move(this.onMove)
				.up(this.onUp)
				.wheel(this.onWheel);
			this.addListening();
			this.debug(["Event Bind,", this.eventHandler]);
		}
		/**
		 * 添加手势的动作，长按，双击，点击等
		 * @description 只有在选中对象时该监听才生效
		 */
		addListening() {
			this.gesture.addListenGesti("click", (ViewObject, position) => {});
			this.gesture.addListenGesti("dbclick", (ViewObject, position) => {
				//  console.log("双击",position);
			});
			this.gesture.addListenGesti("longpress", (ViewObject, position) => {
				// console.log("长按",position);
			});
			this.gesture.addListenGesti("twotouch", (ViewObject, position) => {
				//console.log("二指",position);
				// this.gesture.onDown(this.selectedViewObject, position);
			});
			this.gesture.addListenGesti("globalClick", (position) => {
				// const selected = this.clickViewObject(position);
				// if (selected == null && this.selectedViewObject) {
				//     this.drag.cancel();
				//     this.cancel();
				// }
			});
		}
		//唤醒,可以继续操作
		wakeUp() {
			this.sleep = false;
			this.update();
		}
		cancelEvent() {
			if (this.eventHandler == null)
				return;
			this.eventHandler.disable();
		}
		onDown(v) {
			var _a;
			this.debug(["Event Down,", v]);
			//休眠不执行任何操作
			if (this.sleep)
				return;
			this.eventHandlerState = EventHandlerState.down;
			const event = this.correctEventPosition(v);
			//手势解析处理
			this.gesture.onDown(this.selectedViewObject, event);
			if ((_a = this.selectedViewObject) !== null && _a !== void 0 ? _a : false) {
				if (Array.isArray(event) || this.checkFuncButton(event)) {
					return;
				}
			}
			/**
			 * 处理拖拽的代码块，被选中图册是检测选中的最高优先级
			 * 当有被选中图层时，拖拽的必然是他，不论层级
			 *
			 */
			let selectedViewObject = CatchPointUtil.catchViewObject(this.ViewObjectList, event);
			if (selectedViewObject &&
				this.selectedViewObject === selectedViewObject &&
				!this.selectedViewObject.isLock)
				this.drag.catchViewObject(selectedViewObject.rect, event);
			/**
			 * 画笔代码块 可以有被选中的图层，前提是当前下落的位置必定不能在上一个被选中的图册内
			 *
			 * */
			if (this.selectedViewObject != selectedViewObject ||
				selectedViewObject == null)
				this.writeFactory.onDraw();
			this.update();
		}
		onMove(v) {
			var _a, _b;
			this.debug(["Event Move,", v]);
			//休眠不执行任何操作
			if (this.sleep)
				return;
			if (this.eventHandlerState === EventHandlerState.down) {
				const event = this.correctEventPosition(v);
				//绘制处理,当down在已被选中的图册上时不能绘制
				if (this.writeFactory.current) {
					this.update();
					return (_a = this.writeFactory.current) === null || _a === void 0 ? void 0 : _a
						.onMove(event);
				}
				//手势解析处理
				this.gesture.onMove(this.selectedViewObject, event);
				//手势
				if (Array.isArray(event)) {
					this.gesture.update(event);
					return this.update();
				}
				//拖拽
				this.drag.update(event);
				//有被选中对象才刷新
				if (this.selectedViewObject != null)
					this.update();
			} else {
				const event = this.correctEventPosition(v);
				//Hover检测
				const selectedViewObject = CatchPointUtil.catchViewObject(this.ViewObjectList, event);
				if (selectedViewObject &&
					((_b = this.hoverViewObject) === null || _b === void 0 ? void 0 : _b.key) !=
					selectedViewObject.key) {
					this.callHook("onHover", selectedViewObject);
					this.hoverViewObject = selectedViewObject;
				} else if (!selectedViewObject && this.hoverViewObject) {
					this.callHook("onLeave", this.hoverViewObject);
					this.hoverViewObject = null;
				}
			}
		}
		onUp(v) {
			var _a;
			this.debug(["Event Up,", v]);
			//休眠不执行任何操作
			if (this.sleep)
				return;
			const event = this.correctEventPosition(v);
			//判断是否选中对象
			this.clickViewObject(event);
			this.eventHandlerState = EventHandlerState.up;
			//手势解析处理
			this.gesture.onUp(this.selectedViewObject, event);
			this.drag.cancel();
			//绘制完了新建一个viewObj图册对象
			const writeObj = this.writeFactory.done();
			writeObj.then((value) => {
				if (value) {
					this.addViewObject(value);
				}
			});
			if (((_a = this.selectedViewObject) !== null && _a !== void 0 ? _a : false) && this
				._inObjectArea) {
				this.selectedViewObject.onUp(this.paint);
				//鼠标|手指抬起时提交一次操作
				this.recorder.commit();
			}
			setTimeout(() => this.update(), 100);
			this._inObjectArea = false;
		}
		onWheel(e) {
			const {
				deltaY
			} = e;
			if (this.selectedViewObject != null) {
				if (deltaY < 0)
					this.selectedViewObject.enlarge();
				else
					this.selectedViewObject.narrow();
			}
			this.update();
		}
		/**
		 * 传入一个Vector坐标判断是否选中了图册
		 * @param event
		 */
		clickViewObject(event) {
			const selectedViewObject = CatchPointUtil.catchViewObject(this.ViewObjectList, event);
			if (selectedViewObject !== null && selectedViewObject !== void 0 ? selectedViewObject :
				false) {
				this.debug(["选中了", selectedViewObject]);
				this.callHook("onSelect", selectedViewObject);
				this._inObjectArea = true;
				//之前是否有被选中图层 如果有就取消之前的选中
				if (this.selectedViewObject &&
					selectedViewObject.key != this.selectedViewObject.key) {
					this.selectedViewObject.cancel();
					//换的时候不需要
					//   this.callHook("onCancel", this.selectedViewObject);
				}
				this.selectedViewObject = selectedViewObject;
				//选中后变为选中状态
				this.selectedViewObject.onSelected();
				//不允许在锁定时被拖拽选中进行操作
				if (!selectedViewObject.isLock)
					this.drag.catchViewObject(this.selectedViewObject.rect, event);
				return selectedViewObject;
			}
			return null;
		}
		correctEventPosition(vector) {
			let _vector = new Array();
			if (Array.isArray(vector)) {
				vector.map((item) => {
					_vector.push(item.sub(this.offset));
				});
				return _vector;
			}
			return vector.sub(this.offset);
		}
		checkFuncButton(eventPosition) {
			const _button = this.selectedViewObject.checkFuncButton(eventPosition);
			const result = _button;
			//确保是按钮
			if (result instanceof Button) {
				this._inObjectArea = true;
				const button = result;
				if (button.trigger == FuncButtonTrigger.drag) {
					button.onSelected();
					this.drag.catchViewObject(button.rect, eventPosition);
				} else if (button.trigger == FuncButtonTrigger.click) {
					button.effect();
				}
				return true;
			}
			this.drag.cancel();
			this.gesture.cancel();
			return false;
		}
		callHook(type, arg = null) {
			this.listen.callHooks(type, arg);
		}
		addViewObject(obj) {
			this.ViewObjectList.push(obj);
			this.callHook("onLoad", obj);
			this.update();
		}
		update() {
			//休眠不执行任何操作
			if (this.sleep)
				return;
			/**
			 * 在使用绘制对象时，根据值来判断是否禁止重绘
			 */
			//  if (this.writeFactory.current?.disableCanvasUpdate) return;
			this.debug("Update the Canvas");
			this.callHook("onUpdate", null);
			this.paint.clearRect(0, 0, this.canvasRect.size.width, this.canvasRect.size.height);
			//当前显示标记数组初始化数据，且需要实时更新
			if (this.currentViewObjectState.length != this.ViewObjectList.length) {
				this.currentViewObjectState.push(1);
			}
			this.ViewObjectList.forEach((item, ndx) => {
				if (!item.disabled) {
					//扫除
					this.cleaning(item);
					item.update(this.paint);
				} else if (this.currentViewObjectState[ndx] == 1) {
					//标记过后不会再次标记
					this.currentViewObjectState[ndx] = 0;
					item.cancel();
					this.callHook("onHide", item);
				}
			});
		}
		/**
		 * 扫除没用的对象，根据大小判断
		 * 清扫细微到不可见的对象
		 * @param item
		 */
		cleaning(item) {
			if (item && item.rect) {
				const {
					width,
					height
				} = item.rect.size;
				if (width <= 3 && height <= 3)
					item.hide();
			}
		}
		/**
		 * @description 新增图片
		 * @param ximage
		 * @returns
		 */
		addImage(ximage) {
			this.debug("Add a Ximage");
			if (ximage.constructor.name != "XImage")
				throw Error("不是XImage类");
			const image = ximage;
			const imageBox = new ImageBox(image);
			imageBox.center(this.canvasRect.size);
			this.addViewObject(imageBox);
			setTimeout(() => {
				this.update();
			}, 100);
			return Promise.resolve(imageBox);
		}
		/**
		 * @description 新增文字
		 * @param text
		 * @param options
		 * @returns
		 */
		addText(text, options) {
			const textBox = new TextBox(text, options);
			textBox.center(this.canvasRect.size);
			this.addViewObject(textBox);
			//测试
			// this.selectedViewObject=textBox;
			// this.selectedViewObject.onSelected()
			setTimeout(() => {
				this.update();
			}, 100);
			return Promise.resolve(textBox);
		}
		addWrite(options) {
			this.writeFactory.setConfig(options);
		}
		debug(message) {
			if (!this.isDebug)
				return;
			if (Array.isArray(message))
				console.warn("Gesti debug: ", ...message);
			else
				console.warn("Gesti debug: ", message);
		}
	}
	class _Tools {
		/**
		 * @description 传入 @ViewObject 对象，设置该对象的layer层级
		 * @param selectedViewObject
		 */
		arrangeLayer(ViewObjectList, selectedViewObject, operationType) {
			/**
			 * 层级重构算法，使用换位
			 * 如选中了第3个 @ViewObject ，就将第3个和第一个互换位置
			 */
			const ndx = ViewObjectList.findIndex((item) => item.key === selectedViewObject.key);
			const len = ViewObjectList.length - 1;
			// 0为底部   len为顶部
			switch (operationType) {
				case LayerOperationType.top: {
					let temp = ViewObjectList[len];
					ViewObjectList[len] = selectedViewObject;
					ViewObjectList[ndx] = temp;
				}
				break;
				case LayerOperationType.bottom: {
					let temp = ViewObjectList[0];
					ViewObjectList[0] = selectedViewObject;
					ViewObjectList[ndx] = temp;
				}
				break;
				case LayerOperationType.rise: {
					if (ndx == len)
						break;
					let temp = ViewObjectList[ndx + 1];
					ViewObjectList[ndx + 1] = selectedViewObject;
					ViewObjectList[ndx] = temp;
				}
				break;
				case LayerOperationType.lower: {
					console.log(ndx);
					if (ndx == 0)
						break;
					const temp = ViewObjectList[ndx - 1];
					ViewObjectList[ndx - 1] = selectedViewObject;
					ViewObjectList[ndx] = temp;
				}
				break;
			}
		}
		fallbackViewObject(ViewObjectList, node, kit) {
			if (node == null)
				return;
			const obj = ViewObjectList.find((item) => {
				return item.key == node.key;
			});
			if (obj) {
				switch (node.type) {
					case "position":
						obj.rect.position = node.data;
						break;
					case "angle":
						obj.rect.setAngle(node.data);
						break;
					case "scale":
						obj.rect.setScale(node.data);
						break;
					case "size":
						obj.rect.setSize(node.data.width, node.data.height);
						break;
					case "drag": {
						obj.rect.setSize(node.data.size.width, node.data.size.height);
						obj.rect.setAngle(node.data.angle);
					}
					break;
				}
				obj.didFallback();
			}
			kit.update();
		}
	}

	/**
	 * 初始化该 @Gesti 实例时，由于平台不确定，用户必须传入 @CanvasRenderingContext2D 画笔作为
	 */
	class Gesti {
		constructor(config) {
			Gesti.config = new GestiConfig(config);
		}
		get controller() {
			return this._controller || (this._controller = new GesteControllerImpl(this.kit));
		}
		set debug(value) {
			this.kit.isDebug = true;
		}
		/*
		 * @description 初始化 @Gesti 所代理的画布高宽，在h5端可直接传入 HTMLCanvasElement 自动解析高宽
		 * @param @CanvasRenderingContext2D paint
		 * @param rect
		 */
		init(canvas, paint, rect) {
			if (!canvas && !rect)
				throw Error("未指定Canvas大小或Canvas节点");
			if (typeof document != "undefined" && canvas) {
				let canvasRect = canvas.getBoundingClientRect();
				//优先使用自定义的rect
				if (rect)
					canvasRect = rect;
				if (canvasRect) {
					const g = canvas.getContext("2d");
					g.imageSmoothingEnabled = true;
					g.imageSmoothingQuality = "high";
					this.kit = new ImageToolkit(g, canvasRect);
					canvasConfig.init(this.kit);
					return;
				}
			}
			if (rect)
				this.kit = new ImageToolkit(paint, rect);
			canvasConfig.init(this.kit);
		}
		/**
		 * @description 设置配置，跟构造函数一样
		 * @param config
		 */
		setConfig(config) {
			Gesti.config.setParams(config);
			this.kit.update();
		}
		destroy() {
			this.controller.destroyGesti();
			this._controller = null;
			this.kit = null;
		}
	}
	Gesti.XImage = XImage;
	Gesti.Family = exports.ViewObjectFamily;

	function createTextBoxView(text, options) {
		const textBox = new TextBox(text, options);
		new TextBox(text, options);
		return textBox;
	}

	function createImageBoxView(ximage) {
		const imageBox = new ImageBox(ximage);
		return imageBox;
	}

	function createXImageFun(args) {
		const xImage = new XImage(args);
		return xImage;
	}

	let currentInstance = null;
	const error = (msg) => {
		console.error(msg);
	};
	const warn = (msg) => {
		console.warn(msg);
	};
	const setCurrentInstance = (instance) => {
		currentInstance = instance;
	};
	const getCurrentController = () => useController();
	const createGesti = (config) => {
		const gesti = new Gesti(config);
		setCurrentInstance(gesti);
		return currentInstance;
	};

	function injectHook(type, hook, target = currentInstance, prepend = false) {
		if (!target) {
			error("Target is empty");
			return;
		}
		setCurrentInstance(target);
		const controller = getCurrentController();
		return controller.addListener(type, hook, prepend);
	}
	/**
	 * @description 创建Hooks
	 * @param type
	 * @returns
	 */
	const createHook = (type) => (hook, target = currentInstance, prepend = false) => {
		return injectHook(type, (...args) => hook(...args), target, prepend);
	};
	/**
	 * Hook 分发
	 */
	const onSelected = createHook("onSelect");
	const onHover = createHook("onHover");
	const onLeave = createHook("onLeave");
	const onCancel = createHook("onCancel");
	const onHide = createHook("onHide");
	const onUpdate = createHook("onUpdate");
	const onLoad = createHook("onLoad"); //载入一个可操作对象完毕
	const onDestroy = createHook("onDestroy");
	const onBeforeDestroy = createHook("onBeforeDestroy");
	const removeListener = (type, hook, target = currentInstance) => {
		if (!target)
			return error("Target is empty");
		setCurrentInstance(target);
		const controller = getCurrentController();
		controller.removeListener(type, hook);
	};
	const useController = (target = currentInstance) => {
		if (!target)
			return null;
		return currentInstance.controller;
	};
	/**
	 * @description 预设对象加载,本质上调用importAll
	 * @param type
	 * @returns
	 */
	function createPresets(type) {
		return (target = currentInstance) => {
			if (!target) {
				error("Target is empty");
				return Promise.reject("Target is empty");
			}
			setCurrentInstance(target);
			getCurrentController();
			const map = {
				rect: Widgets.rect,
				circle: Widgets.circle,
				verticalLine: Widgets.verticalLine,
				horizonLine: Widgets.horizonLine,
			};
			const shape = map[type];
			if (!shape) {
				warn("Preset object not found");
				return Promise.reject("Preset object not found");
			}
			return useReader(shape);
		};
	}
	/**
	 * 添加预设图形
	 */
	const addVerticalLine = createPresets("verticalLine");
	const addHorizonLine = createPresets("horizonLine");
	const addRect = createPresets("rect");
	const addCircle = createPresets("circle");
	/**
	 * 创建可操作对象
	 */
	const createTextBox = (text, options) => createTextBoxView(text, options);
	const createImageBox = (xImage) => createImageBoxView(xImage);
	/**
	 * @description 踩踩踩
	 * @param option
	 * @returns
	 */
	const createXImage = (option) => createXImageFun(option);
	/**
	 * @description 文字控制
	 * @param text
	 * @param textBox
	 * @param options
	 * @param target
	 * @returns
	 */
	function textHandler(text, textBox, options, target = currentInstance) {
		textBox.updateText(text, options);
		if (!target) {
			error("Target is empty");
			return Promise.reject("Target is empty");
		}
		setCurrentInstance(target);
		const controller = getCurrentController();
		controller.update();
	}
	/**
	 * @description 使用文字控制Hook
	 * @param textBox
	 * @param target
	 * @returns
	 */
	const useTextHandler = (textBox, target = currentInstance) => (text, options) => {
		if (!textBox || textBox.family != Gesti.Family.text) {
			return error("Not a TextBox object");
		}
		return textHandler(text, textBox, options, currentInstance);
	};
	/**
	 * @description 将可操作对象载入到画布内
	 * @param view
	 * @param target
	 * @returns
	 */
	const loadToGesti = (view, target = currentInstance) => {
		if (!target) {
			error("Target is empty");
			return;
		}
		setCurrentInstance(target);
		const controller = getCurrentController();
		controller.load(view);
	};
	/**
	 * @description 创建涂鸦hook
	 * @param type
	 * @returns
	 */
	const createGraffiti = (type) => (option, target = currentInstance) => {
		if (!target) {
			error("Target is empty");
			return;
		}
		setCurrentInstance(target);
		const controller = getCurrentController();
		controller.addWrite(Object.assign({
			type: type
		}, option));
	};
	const useGraffitiRect = createGraffiti("rect");
	const useGraffitiCircle = createGraffiti("circle");
	const useGraffitiLine = createGraffiti("line");
	const useGraffitiWrite = createGraffiti("write");
	const useCloseGraffiti = createGraffiti("none");
	/**
	 * @description 导入json到画布内,该json数据格式必须由 exportAll Hook导出
	 * @param json
	 * @param target
	 * @returns
	 */
	const importAll = (json, target = currentInstance) => {
		if (!target) {
			error("Target is empty");
			return Promise.reject("Target is empty");
		}
		if (!json) {
			warn("Json is empty");
			return Promise.reject("json is empty");
		}
		setCurrentInstance(target);
		const controller = getCurrentController();
		return controller.importAll(json);
	};
	/**
	 * @description 导出可操作对象为json格式的 Array\<Object\>
	 * 注意: 功能使用离屏渲染
	 * @param target
	 * @returns
	 */
	const exportAll = (offscreenPainter, target = currentInstance) => {
		if (!target) {
			error("Target is empty");
			return Promise.reject("Target is empty");
		}
		setCurrentInstance(target);
		const controller = getCurrentController();
		return controller.exportAll(offscreenPainter);
	};
	const createDragButton = (view) => new DragButton(view);
	const createHorizonButton = (view) => new HorizonButton(view);
	const createRotateButton = (view) => new RotateButton(view);
	const createLockButton = (view) => new LockButton(view);
	const createUnlockButton = (view) => new UnLockButton(view);
	const createCloseButton = (view) => new CloseButton(view);
	const createVerticalButton = (view) => new VerticalButton(view);
	const createMirrorButton = (view) => new MirrorButton(view);
	/**
	 * @description 给某个可操作对象安装按钮
	 * @param view
	 * @param button
	 */
	const installButton = (view, button) => {
		if (Array.isArray(button)) {
			button.forEach((item) => view.installButton(item));
		} else {
			view.installButton(button);
		}
	};
	const unInstallButton = (view, button) => {
		if (Array.isArray(button)) {
			view.unInstallButton(button);
		} else {
			view.unInstallButton([button]);
		}
	};
	/**Do Hook */
	const doSomething = (type) => (view, target = currentInstance) => {
		if (!target) {
			error("Target is empty");
			return;
		}
		setCurrentInstance(target);
		const controller = getCurrentController();
		switch (type) {
			case "select":
				controller.select(view);
				break;
			case "layerLower":
				controller.layerLower(view);
				break;
			case "layerBottom":
				controller.layerBottom(view);
				break;
			case "layerRise":
				controller.layerRise(view);
				break;
			case "layerTop":
				controller.layerTop(view);
				break;
			case "unLock":
				controller.unLock(view);
				break;
			case "lock":
				controller.lock(view);
				break;
			case "upward":
				controller.upward(view);
				break;
			case "downward":
				controller.downward(view);
				break;
			case "leftward":
				controller.leftward(view);
				break;
			case "rightward":
				controller.rightward(view);
				break;
			case "update":
				controller.update();
				break;
			case "cancel":
				controller.cancel(view);
				break;
			case "cancelEvent":
				controller.cancelEvent();
				break;
			case "cancelAll":
				controller.cancelAll();
				break;
			case "destroyGesti": {
				currentInstance.destroy();
				setCurrentInstance(null);
			}
		}
		setTimeout(() => controller.update(), 10);
	};
	const doSelect = doSomething("select");
	const doLayerLower = doSomething("layerLower");
	const doLayerBottom = doSomething("layerBottom");
	const doLayerTop = doSomething("layerTop");
	const doLayerRise = doSomething("layerRise");
	const doLock = doSomething("lock");
	const doUnLock = doSomething("unLock");
	const doUpward = doSomething("upward");
	const doDownward = doSomething("downward");
	const doLeftward = doSomething("leftward");
	const doRightward = doSomething("rightward");
	const doUpdate = doSomething("update");
	const doCancel = doSomething("cancel");
	const doCancelAll = doSomething("cancelAll");
	const doCancelEvent = doSomething("cancelEvent");
	const doDestroyGesti = doSomething("destroyGesti");
	const doCenter = (axis, view, target = currentInstance) => {
		//不安全的做法
		target.controller.center(axis, view);
	};
	const doRotate = (angle, existing, view, target = currentInstance) => {
		//不安全的做法
		target.controller.rotate(angle, existing, view);
	};
	/**
	 * 转换json成可读取对象
	 * @param json
	 * @returns
	 */
	const useReader = (json) => {
		const reader = new GestiReader();
		return reader.getObjectByJson(json);
	};
	/**
	 * @description 获取当前选中对象
	 * @param target
	 * @returns
	 */
	const currentViewObject = (target = currentInstance) => {
		if (!target) {
			error("Target is empty");
			return;
		}
		setCurrentInstance(target);
		const controller = getCurrentController();
		if (!controller)
			error("Gesti not registered");
		return controller.currentViewObject;
	};
	const drive = (type) => {
		return (e, target = currentInstance) => {
			setCurrentInstance(target);
			const controller = getCurrentController();
			if (!controller)
				error("Gesti not registered");
			if (type == "move")
				controller.move(e);
			else if (type == "down")
				controller.down(e);
			else if (type == "up")
				controller.up(e);
			else if (type == "wheel")
				controller.wheel(e);
		};
	};
	const driveMove = drive("move");
	const driveUp = drive("up");
	const driveDown = drive("down");
	const driveWheel = drive("wheel");

	// const canvas: HTMLCanvasElement = document.querySelector("#canvas");
	// const offScreenCanvas:HTMLCanvasElement=document.querySelector("#offScreenCanvas");
	// const img: HTMLImageElement = document.querySelector("#dog");
	// canvas.width = 500;
	// canvas.height = 500;
	// offScreenCanvas.width=10000;
	// offScreenCanvas.height=500;
	// const g = canvas.getContext("2d");
	// const offScreenPainter=offScreenCanvas.getContext("2d");
	// const painter: Painter = new Painter(g);
	// const gesti = createGesti({
	//   dashedLine: true,
	// });
	// gesti.init(canvas);
	// const controller = useController();
	// const ximage = createXImage({
	//   data: img,
	//   width: img.width,
	//   height: img.height,
	//   scale: 1,
	// });
	// const imageBox = createImageBox(ximage);
	// const lockButton = new LockButton(imageBox);
	// const unLockButton = new UnLockButton(imageBox);
	// installButton(imageBox, [
	//   lockButton,
	//   unLockButton,
	//   createDragButton(imageBox),
	// ]);
	// doCenter(null, imageBox);
	//   loadToGesti(imageBox);
	//   const textBox=createTextBox("卧槽",{});
	// textBox.installButton(createDragButton(textBox))
	//   loadToGesti(textBox)
	// doUpdate();
	// document.getElementById("import").addEventListener("click",()=>{
	//   console.log("导入")
	//   importAll(window.localStorage.getItem("aa")).then(e=>{
	//     console.log("导入成功")
	//   })
	// })
	// document.getElementById("export").addEventListener("click",()=>{
	//   console.log("导出")
	//   exportAll(offScreenPainter).then(json=>{
	//    window.localStorage.setItem("aa",json);
	//    console.log("导出成功")
	//   })
	// })
	// const clazzList={
	//   CloseButton,
	//   LockButton
	// };
	// console.log(new clazzList['LockButton'](textBox));

	exports.CloseButton = CloseButton;
	exports.DragButton = DragButton;
	exports.HorizonButton = HorizonButton;
	exports.ImageBox = ImageBox;
	exports.LockButton = LockButton;
	exports.MirrorButton = MirrorButton;
	exports.RotateButton = RotateButton;
	exports.TextBox = TextBox;
	exports.UnLockButton = UnLockButton;
	exports.VerticalButton = VerticalButton;
	exports.WriteViewObj = WriteViewObj;
	exports.XImage = XImage;
	exports.addCircle = addCircle;
	exports.addHorizonLine = addHorizonLine;
	exports.addRect = addRect;
	exports.addVerticalLine = addVerticalLine;
	exports.createCloseButton = createCloseButton;
	exports.createDragButton = createDragButton;
	exports.createGesti = createGesti;
	exports.createHorizonButton = createHorizonButton;
	exports.createImageBox = createImageBox;
	exports.createLockButton = createLockButton;
	exports.createMirrorButton = createMirrorButton;
	exports.createRotateButton = createRotateButton;
	exports.createTextBox = createTextBox;
	exports.createUnlockButton = createUnlockButton;
	exports.createVerticalButton = createVerticalButton;
	exports.createXImage = createXImage;
	exports.currentViewObject = currentViewObject;
	exports.default = Gesti;
	exports.doCancel = doCancel;
	exports.doCancelAll = doCancelAll;
	exports.doCancelEvent = doCancelEvent;
	exports.doCenter = doCenter;
	exports.doDestroyGesti = doDestroyGesti;
	exports.doDownward = doDownward;
	exports.doLayerBottom = doLayerBottom;
	exports.doLayerLower = doLayerLower;
	exports.doLayerRise = doLayerRise;
	exports.doLayerTop = doLayerTop;
	exports.doLeftward = doLeftward;
	exports.doLock = doLock;
	exports.doRightward = doRightward;
	exports.doRotate = doRotate;
	exports.doSelect = doSelect;
	exports.doUnLock = doUnLock;
	exports.doUpdate = doUpdate;
	exports.doUpward = doUpward;
	exports.driveDown = driveDown;
	exports.driveMove = driveMove;
	exports.driveUp = driveUp;
	exports.driveWheel = driveWheel;
	exports.exportAll = exportAll;
	exports.importAll = importAll;
	exports.inToPx = inToPx;
	exports.installButton = installButton;
	exports.loadToGesti = loadToGesti;
	exports.mmToIn = mmToIn;
	exports.onBeforeDestroy = onBeforeDestroy;
	exports.onCancel = onCancel;
	exports.onDestroy = onDestroy;
	exports.onHide = onHide;
	exports.onHover = onHover;
	exports.onLeave = onLeave;
	exports.onLoad = onLoad;
	exports.onSelected = onSelected;
	exports.onUpdate = onUpdate;
	exports.ptToPx = ptToPx;
	exports.removeListener = removeListener;
	exports.unInstallButton = unInstallButton;
	exports.useCloseGraffiti = useCloseGraffiti;
	exports.useController = useController;
	exports.useGraffitiCircle = useGraffitiCircle;
	exports.useGraffitiLine = useGraffitiLine;
	exports.useGraffitiRect = useGraffitiRect;
	exports.useGraffitiWrite = useGraffitiWrite;
	exports.useReader = useReader;
	exports.useTextHandler = useTextHandler;

	Object.defineProperty(exports, '__esModule', {
		value: true
	});

}));